So, I am familiar with the fact that you cannot use a callback function on jQuery's .css function. Instead, I used the setTimeout function:
$('#header-nav').css({'left': leftBstr});
posBstr = '.level' + posB.toString();
setTimeout(function(e){
$('#header-nav ul' + posBstr).removeClass('menu-active');
}, 300);
This code is meant for a mobile menu animation. There are two typed of buttons:
go further into the menu (child categories)
go back (parent category)
But, when using the setTimeout function, when I click too fast, the menu disappears, because of the removed class menu-active.
I already tried putting the setTimeout function inside a var, and use the clearTimeout function, but that did not work.
My question: is there another way to recreate the callback function on the .css function, without using setTimeout?
You can try to use the promise
The .promise() method returns a dynamically generated Promise that is resolved once all actions of a certain type bound to the collection, queued or not, have ended.
$('.element').css("color","yellow").promise().done(function(){
alert( 'color is yellow!' );
});
Related
Sometimes I make a function and call the function later.
Example:
function example { alert('example'); }
example(); // <-- Then call it later
Somehow, some functions cannot be called. I have to call those functions inside:
$(function() { });
What do $(function() {}); and (function() { }); mean, and what's the difference/purpose of these?
$(function() { ... });
is just jQuery short-hand for
$(document).ready(function() { ... });
What it's designed to do (amongst other things) is ensure that your function is called once all the DOM elements of the page are ready to be used.
However, I don't think that's the problem you're having - can you clarify what you mean by 'Somehow, some functions are cannot be called and I have to call those function inside' ?
Maybe post some code to show what's not working as expected ?
Edit: Re-reading your question, it could be that your function is running before the page has finished loaded, and therefore won't execute properly; putting it in $(function) would indeed fix that!
The following is a jQuery function call:
$(...);
Which is the "jQuery function." $ is a function, and $(...) is you calling that function.
The first parameter you've supplied is the following:
function() {}
The parameter is a function that you specified, and the $ function will call the supplied method when the DOM finishes loading.
It's just shorthand for $(document).ready(), as in:
$(document).ready(function() {
YOUR_CODE_HERE
});
Sometimes you have to use it because your function is running before the DOM finishes loading.
Everything is explained here: http://docs.jquery.com/Tutorials:Introducing_$(document).ready()
Some Theory
$ is the name of a function like any other name you give to a function. Anyone can create a function in JavaScript and name it $ as shown below:
$ = function() {
alert('I am in the $ function');
}
JQuery is a very famous JavaScript library and they have decided to put their entire framework inside a function named jQuery. To make it easier for people to use the framework and reduce typing the whole word jQuery every single time they want to call the function, they have also created an alias for it. That alias is $. Therefore $ is the name of a function. Within the jQuery source code, you can see this yourself:
window.jQuery = window.$ = jQuery;
Answer To Your Question
So what is $(function() { });?
Now that you know that $ is the name of the function, if you are using the jQuery library, then you are calling the function named $ and passing the argument function() {} into it. The jQuery library will call the function at the appropriate time. When is the appropriate time? According to jQuery documentation, the appropriate time is once all the DOM elements of the page are ready to be used.
The other way to accomplish this is like this:
$(document).ready(function() { });
As you can see this is more verbose so people prefer $(function() { })
So the reason why some functions cannot be called, as you have noticed, is because those functions do not exist yet. In other words the DOM has not loaded yet. But if you put them inside the function you pass to $ as an argument, the DOM is loaded by then. And thus the function has been created and ready to be used.
Another way to interpret $(function() { }) is like this:
Hey $ or jQuery, can you please call this function I am passing as an argument once the DOM has loaded?
I think you may be confusing Javascript with jQuery methods. Vanilla or plain Javascript is something like:
function example() {
}
A function of that nature can be called at any time, anywhere.
jQuery (a library built on Javascript) has built in functions that generally required the DOM to be fully rendered before being called. The syntax for when this is completed is:
$(document).ready(function() {
});
So a jQuery function, which is prefixed with the $ or the word jQuery generally is called from within that method.
$(document).ready(function() {
// Assign all list items on the page to be the color red.
// This does not work until AFTER the entire DOM is "ready", hence the $(document).ready()
$('li').css('color', 'red');
});
The pseudo-code for that block is:
When the document object model $(document) is ready .ready(), call the following function function() { }. In that function, check for all <li>'s on the page $('li') and using the jQuery method .CSS() to set the CSS property "color" to the value "red" .css('color', 'red');
This is a shortcut for $(document).ready(), which is executed when the browser has finished loading the page (meaning here, "when the DOM is available"). See http://www.learningjquery.com/2006/09/introducing-document-ready. If you are trying to call example() before the browser has finished loading the page, it may not work.
I have two functions, one is for expanding tree view (i.e. ExpandAll()) and second one is for removing particular type of elements from that tree view (i.e. RemoveAbElements()).
ExpandAll() method checks if there are child nodes under the selected node. If not then it retrieves the child elements by ajax call. So now I am calling these methods as follows :
function(){
ExpandAll();
RemoveAbElements();
}
Now my problem here is, there is a callback in ExpandAll() method and it gets called for each child node expanded (which is expected). Now here the callback gets called even after the execution of RemoveAbElements() method. I want to execute ExpandAll() method and all of its callbacks before RemoveAbElements() execution. I tried lots of things for this but none worked. please help.
There could a be lot of ways you could be approaching.
One way could be, passing the RemoveAbElements itself to ExpandAll.
So you could be passing it as
ExpandAll(RemoveAbElements);
or, When you don't want to call RemoveElements, as :
ExpandAll();
And ExpandAll could be modified to accept the callback :
ExpandAll(callbackFunc) {
//... Do Work Here
if(callbackFunc) callbackFunc();
}
Or use triggerhandler & on if there is a jquery object, as suggested by slinky2000.
If I've understood you correctly you need to add a listener to EXpandAll() and when it's finished everything call RemoveAbElements()
I would look at jquerys custom event triggering:
http://api.jquery.com/trigger/
// Listen for finish
$('#tree').on('customFinishedEvent', function(event) {
alert('finished');
});
// On finished loading and expanding
$("#tree").trigger('customFinishedEvent');
I get some data using AJAX, prepend element to body and then display it. After it's displayed I need to perform some client-side operations on a new element (say, I need to render Latex using codecogs' script). My code looks like this:
$.ajax({
/* ... */
success: function(data){
/* new element generation... */
$(newelement).fadeIn(100, LatexIT.render('*'));
},
/* ... */ });
As you can see I call LatexIT.render('*') as a callback from fadeIn. It should perform whatever LatexIT.render('*') does right after the animation is over. But when called from $.ajax success the callback doesn't work, although fade itself occures normally.
UPDATE: I tried to replace LatexIT.render('*') with any simple function but it doesn't work. And fadeIn(100, function () { LatexIT.render('*') }); does work when called from outside of ajax success.
LatexID.render('*') is the syntax to call the .render method rather than bind it. Unless that itself returns a function, which is unlikely, you need to use this syntax:
.fadeIn(100, function () { LatexIT.render('*') });
You could also do:
.fadeIn(100, LatexIT.render.bind(undefined, '*'))
assuming the browsers you need to support have .bind
There you are not giving it a success callback, you are executing your render and giving what the render method returns to the complete argument of the fade animation, which is actually not a function that the animation can call at the end.
You should just wrap it into an anonymous function:
$(newElement).fadeIn(100, function() { LatexIT.render("*"); })
I am currently making use of Simon Willson's addLoadEvent function to add functions that I want to run after the load event. I ran into a problem wherein the the function I passed to the addLoadEvent function referenced a div that had not yet been loaded by the DOM and so my action (showing the div) did not do anything. When I changed to using the jQuery $(document).ready function, the div has been loaded by the DOM and I can execute actions with it (make it show up).
So, a couple questions. Why is my function being executed before the DOM has completed loaded using the above function? Is there a way to delay it? The other alternative that I can think of is passing in a function to a jquery equivalent:
function jqueryAddReadyEvent(myFunc)
{
$(document).ready(function()
{
//execute already existing functions
//add a new function to the ready event
myFunc();
}
}
When I try the above code, I get a javascript error "myFunc is not a function". Is there a way to generically pass in a function to the jquery ready function and have it execute? Equivalent to the following:
$(document).ready(function()
{
funcA();
}
$(document).ready(function()
{
funcB();
}
...//more of the same
Replaced with the following:
jQueryAddReadyEvent(funcA);
jQueryAddReadyEvent(funcB);
You can just do:
$(document).ready(myFunc);
to attach functions to the DOM ready event. Here's the fiddle: http://jsfiddle.net/padtE/
If you will require many functions to be added then I suggest you do the following:
Create an array that will old all the functions you want to call.
Add functions to that array as you please.
In the .ready(function() { ... }) call every function in that array.
You're set.
It looks correct to me. Most likely you are calling it with something not a function.
Btw you can shorten this to:
var jqueryAddReadyEvent = $(document).ready
or just use $(document).ready() directly for the same effect, as it specifically does what you want to do, run functions after the load, and is actually shorter.
$(document).ready(funcA);
$(document).ready(funcB);
function jqueryAddReadyEvent(myFunc) {
$(myFunc);
}
jqueryAddReadyEvent(function() {
alert('hello world');
});
Demo: http://jsfiddle.net/AlienWebguy/UzMLE/
when i use jquery to create an element(a div, for example) in a callback function, it doesn't allow me to manipulate the newly created element outside the callback function, how can I get around this?
here is the example:
$.get('menu.xml',function(data){
//create a new element with an ID called "#newElement"
})
//I can't select the element outside the callback function so the following code dosen't work:
$('#newElement').css('background','black');
You can select it outside, but not yet, that $.get() callback takes some time to run (it has to get the data from the server, the callback happens later, when that finishes), so when you do this:
$('#newElement').css('background','black');
That element isn't there yet (and so the selector doesn't find anything...it's running before that callback creating it does), you need to wait until the callback finishes before continuing any code that needs elements created by it. Like this:
$.get('menu.xml',function(data){
//create a new element with an ID called "#newElement"
//kick off stuff that uses "#newElement"
$('#newElement').css('background','black');
});
$.get('menu.xml',function(data){
//create a new element with an ID called ".newElement"
$('<div/>').val(data).attr('id','newElement').css('background','black').append('#container');
})
Try modifying the element within the callback, also try using the class instead of the id
Judging from the code you've shown, it seems your trying to manipulate '#newElement' before it exists. The reason for that is '#newElement' is created in the callback of '$.get'.
Its important to remember that asynchronous functions in javascript don't cause the thread to wait, this is why callbacks exist. So, before your callback function for '$.get' has even been executed, you are trying to manipulate '#newElement'.
For instance, if you adjust your code to:
$.get('menu.xml',function(data){
//create a new element with an ID called "#newElement"
....
$('#newElement').css('background','black');
})
You will find that it works.