I am calling the Typeset method as in code below. Right now, I have the callback function without any arguments and this works without any problems. However, I would prefer to pass an argument to the callback function of typeSetDone rather than use a global variable called scripts in the callback function.
Question : Is it possible to pass an argument to a callback function in this situation, and if yes then how would I pass it?
var scripts = [];
function someMethod()
MathJax.Hub.Queue(["Typeset", MathJax.Hub, element, typeSetDone]);
}
function typeSetDone() {
//do something here using the global scripts variable
}
The easiest is to queue the function right afterwards, e.g.,
var scripts = [];
function someMethod()
MathJax.Hub.Queue(["Typeset", MathJax.Hub, element]);
MathJax.Hub.Queue(typeSetDone);
}
function typeSetDone() {
//do something here using the global scripts variable
}
You might want to search the MathJax User Group for other examples.
Related
I have seen several examples of java script functions with parameters passed which are not located in the script but are implicitly passed in. For example:
function myFunction(xml) {
var xmlDoc = xml.responseXML;
document.getElementById("demo").innerHTML =
xmlDoc.getElementsByTagName("title")[0].childNodes[0].nodeValue;
}
Where is the "xml" defined or listed? Where can i find a listing of other implicit parameters?
I've also seen a function with the following:
$("body").click(function (event) {
// Do body action
var target = $(event.target);
if (target.is($("#myDiv"))) {
// Do div action
}
});
Where is "event" coming from or listed?
Thanks in advance.
These variables are called (function) parameters. This is a common feature of most programming languages. They are defined with a function, and simply serve as variables that are defined within the function. They do not need to be defined outside of the function previously, because they exist only for the function.
I believe you're confused because they're not declared with var (as they shouldn't be) because you're calling them "implicit variables." However, they are not implicit; they are defined with the function.
You can find the parameters to a function by looking at the documentation for the function, if you are using a library like jQuery. For example, the .click() function handler is defined like:
(If you can't see the image, it shows .click(handler), where handler is of Type: Function(Event eventObject))
As you can see, it defines the function parameter eventObject which you can "pass" in when you invoke a function. You can use any valid variable name to do so.
You can see this MDN documentation for more information on parameters.
Where is the "xml" defined or listed? Where can i find a listing of other implicit parameters?
Is listed in the very function definition. When I define a function like:
function greet( name , greeting ){
console.log('hi ' + name );
console.log(greeting);
}
name and greeting vars are just defined within the parenthesis in the function definition. You can just call that function passing literals or variables:
greeting('peter' , 'have a nice day');
//or:
var name = 'Francisco';
var greeting = 'qué pasa hombre';
greet(name , greeting);
In the second example, name and greeting vars happen to be called exactly like the internal function parameters. That is just by case, could be too:
var theAame = 'Francisco';
var theGreeting = 'qué pasa hombre';
greet(theName , theGreeting);
And would work exactly the same. Also, in javaScript, you can just pass more parameters to a function than the parameters actually defined in the function, and access them with the arguments keyword or the ES6 spread syntax.
This is javaScript bread and butter and any search on how does arguments and parameters work in javaScript will be useful to you. However, your second question is more tricky.
You're also asking about this kind of code:
$("body").click(function (event) {
// Do body action
var target = $(event.target);
if (target.is($("#myDiv"))) {
// Do div action
}
});
This is similar, but also is more complex. Here $("body").click() is a function that takes a parameter. This parameter happens to be another function. This is a feature not supported in some languages, but is pretty straightforward in javascript. You could also wrote that code this way:
function reactToClick (event) {
// Do body action
var target = $(event.target);
if (target.is($("#myDiv"))) {
// Do div action
}
}
$("body").click( reactToClick );
But, who is then calling that reactToClick function with that event parameter? Well, in this case, the browser does.
Any browser has some API's to register to events -like clicks- with function callbacks, and $.click() is just some syntactic helper over that mechanism. Since is the browser who is ultimately calling the function, is difficult to fully understand the internals -and I must admit I don't-.
However, you can set up your own non-browser-api-dependant javaScript code that invoke callbacks, and the parameters set up and function invocations works the same way:
function theCallback( name , options ){
console.log('Im a callback function fired by someCallbackRegister whenever its fire methods is called');
console.log('my callbackRegister name is: ' + name);
console.log('and the options provided in this call are: ' + options);
}
function someCallbackRegister( callback , registerName ){
return {
fire : function(options){
callback(registerName , options );
}
}
}
var listener = someCallbackRegister( theCallback , 'Johhny');
listener.fire({ foo : 'bar'});
In this example, is the listener who is invoking theCallback after it's fire method call, and setting up all the parameters to that theCallback function properly, just like the browser manages to pass an event object to the callback function you pass to $.click().
Hope this helps :-)
PS: This video about the javaScript event loop helped me a lot to understand how the browser api's work.
function myFunction(xml) {
}
Whoever invokes this myFunction will pass the details which will be saved to variable xml. It's JS language syntax - you don't need to define the type of variable here unlike Java.
Similarly, when you do this:
$("body").click(function (event) {
});
JS internally registers a callback method whenever the body is clicked. It internally passes the event details to the function. You can do console.log(event) and see what all details are listed there
I'm using PhantomJS v2.0 and CasperJS 1.1.0-beta3. I want to query a specific part inside the page DOM.
Here the code that did not work:
function myfunc()
{
return document.querySelector('span[style="color:#50aa50;"]').innerText;
}
var del=this.evaluate(myfunc());
this.echo("value: " + del);
And here the code that did work:
var del=this.evaluate(function()
{
return document.querySelector('span[style="color:#50aa50;"]').innerText;
});
this.echo("value: " + del);
It seems to be the same, but it works different, I don't understand.
And here a code that did also work:
function myfunc()
{
return document.querySelector('span[style="color:#50aa50;"]').innerText;
}
var del=this.evaluate(myfunc);
this.echo("value: " + del);
The difference here, I call the myfunc without the '()'.
Can anyone explain the reason?
The problem is this:
var text = this.evaluate(myfunc());
Functions in JavaScript are first class citizen. You can pass them into other functions. But that's not what you are doing here. You call the function and pass the result into evaluate, but the result is not a function.
Also casper.evaluate() is the page context, and only the page context has access to the document. When you call the function (with ()) essentially before executing casper.evaluate(), you erroneously try to access the document, when it is not possible.
The difference to casper.evaluate(function(){...}); is that the anonymous function is defined and passed into the evaluate() function.
There are cases where a function should be called instead of passed. For example when currying is done, but this is not applicable to casper.evaluate(), because it is sandboxed and the function that is finally run in casper.evaluate() cannot use variables from outside. It must be self contained. So the following code will also not work:
function myFunc2(a){
return function(){
// a is from outer scope so it will be inaccessible in `evaluate`
return a;
};
}
casper.echo(casper.evaluate(myFunc2("asd"))); // null
You should use
var text = this.evaluate(myfunc);
to pass a previously defined function to run in the page context.
It's also not a good idea to use reserved keywords like del as variable names.
I want to call jquery function in side of java script. My code is:
<script type="text/javascript">
function calljs(){
getUserMail(usermMail);
}
$(function() {
function getUserMail(usermMail) {
***some code*****
}
});
</script>
I got error from browser console:
ReferenceError: getUserMail is not defined.
How to solve this problem?
As far as i understand, the method is not defined when the method is being called. So define it before it is getting called
<script type="text/javascript">
function getUserMail(usermMail) {
***some code*****
}
function calljs(){
getUserMail(usermMail);
}
$(function() {
//
});
</script>
hope it helps
If it is really compulsory to put the function with in the jquery's ready callback (which I don't think is compulsory) use the following way
<script type="text/javascript">
var getUserMail = null;
function calljs(){
if ( null !== getUserMail ) {
getUserMail(usermMail);
}
}
$(function() {
getUserMail = function (usermMail) {
***some code*****
}
});
</script>
You can simply do ,
$(document).ready(function(event) {
getUserMail(usermMail);
});
and define it like ,
function getUserMail(usermMail){
. . .
}
or using jquery ,
$(document).on('click', ".selector", function);
trigger a function on an event
getUserMail is not defined in a scope that is accessible to calljs. This is why you get the ReferenceError; in the context in which you tried to invoke getUserMail there was no function with that name available.
// At this point nothing is defined
function calljs(){
getUserMail(usermMail);
}
// now calljs is defined as a global and can be invoked from anywhere
$(function() { // this line is calling a function named $ (an alias for jQuery)
// and passing it an anonymous function as a parameter.
function getUserMail(usermMail) { // This function is being defined inside
// the scope of the anonymous function,
// it can be used anywhere inside the
// anonymous function but not outside it.
// ***some code*****
}
});
// we are now outside the scope of the anonymous function,
// getUserMail is no longer in our scope and can't be called from here.
The easiest and likely best solution for most situations would be to make sure that any functions that call each other are in the same scope.
From what I can tell you don't really need calljs, you were just trying to use it to poke a hole into the scope of the anonymous function where getUserMail is defined.
Instead you should probably get rid of calljs and move any code that is calling getUserMail inside the ready callback. If getUserMail needs to wait for the ready callback to be fired before you call it, any code that invokes it also should be inside the ready callback too. (Things like event handlers that call it should already be inside the ready callback anyway.)
If there is a reason that you can't move it into the ready callback, such as something in another .js file needs to be able to call it etc, your application might be too complicated to be realistically maintained as jQuery soup. It might be worth the effort to port it to a framework such as Ember or Angular.
Also so you know, there is no need to use the type attribute on your script tags. JavaScript is the only language that has wide support in the browser and all browsers default to using JavaScript for script tags.
In my jQuery scripts, when the user closes a menu with an animation, I have to call a function after the closing animation is finished. I want to assign this function dynamically by calling a function openStrip() with a parameter. My code looks like:
var FUNCTION_JUST_AFTER_MENU_CLOSE = function(){};
function openStrip(stripId){
FUNCTION_JUST_AFTER_MENU_CLOSE = function(){
createStrip(stripId);
});
}
if I call openStrip("aStripId"), I expect FUNCTION_JUST_AFTER_MENU_CLOSE to be:
// #1
function(){
createStrip("aStripId");
}
whereas my current code gives:
//#2
function(){
createStrip(stripId);
}
i.e, the parameter passed to the function openStrip() is lost while assigning the function() to the variable FUNCTION_JUST_AFTER_MENU_CLOSE.
How can I avoid this.
EDIT: I discovered that my code is actually working. The problem was elsewhere. I got confused because when I looked at Chrome's debugger, it was showing me the function definition as is (#2 in above). But when it actually went down executing that function later in the code, it did evaluate the values of the passed argument, and endedup executing #1.
Thanks for the answer though. I am marking it correct because that is perhaps a better way of assigning the function.
The best way is to return a function, from openStrip like this
function openStrip(stripId) {
return function() {
createStrip(stripId);
};
}
For example,
function openStrip(stripId) {
return function() {
console.log(stripId);
};
}
openStrip("aStripId")();
# aStripId
openStrip("bStripId")();
# bStripId
You can even assign the function objects returned to different variables and use them later on
var aStrip = openStrip("aStripId");
aStrip();
# aStripId
aStrip();
# aStripId
I'm trying to build an API in JS that will perform some operations and then execute the callback that's registered in AS when it's done. Because it's an API, I am just providing a JS method signature for another developer to call in Flash. Thus, the callback name that's registered in the AS part of the code should be a parameter that's passed in to the JS API in order for JS to communicate back to Flash.
For example:
[AS3 code]
ExternalInterface.addCallback("flashCallbackName", processRequest);
ExternalInterface.call("namespace.jsFnToCall", flashCallbackName);
function processRequest(data:String):void
{
//do stuff
}
[JS code]
var namespace =
{
jsFnToCall: function(callback)
{
//Do stuff in this function and then fire the callback when done.
//getFlashMovie is just a util function that grabs the
//Flash element via the DOM; assume "flash_id"'s a global var
//Below does not work...it's what I'd be ideally be doing some how.
getFlashMovie(flash_id).callback(data);
}
};
Because the definition of the function is in AS, I can't use the window[function name] approach. The only way I can think of is to build the callback in a string and then use the eval() to execute it.
Suggestions? T.I.A.
Well, I can think of one thing I would try, and one thing that would work.
What I would try first.
getFlashMovie(flash_id)['callback'](data);
What would work: Have the callback always be the same, say callback. The first parameter to the callback could be used to determine what actual function to call in flash. For example:
function callback($fn:String, $data:*) {
// either
this[$fn]($data);
// or
switch ($fn) {
case "callback1":
DoSomeCallback($data);
break;
}
Additionally passing the objectID makes it a bit simpler:
ExternalInterface.addCallback("flashCallbackName", processRequest);
ExternalInterface.call("namespace.jsFnToCall", ExternalInterface.objectID, "flashCallbackName");
Then in your JS:
var namespace =
{
jsFnToCall: function(objectID, callback)
{
//Do stuff in this function and then fire the callback when done.
document[objectID][callback](data);
}
};