I want to call a function after the css has been changed. For Example something like this
$("#ContentDiv").css('height','500px').change(function(){
alert('changed');
});
Call function immediately after above css change. I cannot use setTimeout or other timeouts. Actually i have applied some css animation for 1 sec which cause contentdiv to resize for 1 sec and that's why if i call a function immediately like this
$("#ContentDiv").css('height','500px');
myfunction();
myfunction() will start executing while the height is still not changed.
Thanks to John Smith for correcting my question, he suggested good but i could not find to accept his changes.
There is a DOMAttrModified event that is fired on some browsers that you could catch to detect this. You can probably use PropertyChanged on IE, but DOMAttrModified should work on Chrome/Firefox etc.
Something like this:
document.documentElement.addEventListener('DOMAttrModified', function(evt){
if (evt.attrName === 'class') {
// Code
}
}, false);
EDIT: Based on your update, if you just want to call code after the animation is done, and you are using jQuery to do the animation, you can chain a callback function to the animation, please refer to the documentation: http://api.jquery.com/animate/
Just call the function.
$("#ContentDiv").css('height','500px');
myFunction();
Related
I'm having the strangest issue when I'm calling in functions on an event. I'm trying to get a function to run when the window is resized using $(window).resize() but it seems to fire the function as soon as the DOM loads then never again.
I'm probably missing something really simple here but I've been looking at it all day and I need a bit of outside help.
I've created a watered down version on JSfiddle that does the same thing but using $('a').click() instead of $(window).resize() so it's a bit easier to test. As the same issue is cropping up I have a feeling there's something wrong with my function but I just can't see it.
Link is here http://jsfiddle.net/sambeckhamdesign/APLZ2/1/
Try:
$('a').click(function(){
alert('hello');
}, imageResizer());
You are running the function and sending it's output into the jQuery thingy as a parameter:
$('a').click(alert('hello'), imageResizer());
instead, try this:
$('a').click(function() {alert('hello'); imageResizer(); });
This provides an anonyomous function, which will be run when the item is clicked, calling imageResizer(), whereas the way you had it, it ran the imageResizer() function and put it's return value into the onclick handler. The reason it didn't work later on was because it would have been treating whatever the return value of the imageResizer() function was as code that it was trying to run.
You are triggering the event instead of assigning an handler to it
$('a').click(alert('hello'), imageResizer());
Should be
$('a').click(function(event) {
event.preventDefault(); // I suppose you will want that ... it will avoid your window jumping to the top when you click due to the href="#"
alert('hello');
imageResizer();
});
From what I understand using .stop() will prevent the callback functions to fire, right?
Unfortunately, it seems that this does not work in my current script:
newSubMenu.stop().slideToggle(250, function() {
newSubMenu.css('visibility', 'visible').addClass('open');
});
The animation now stops when double clicking, but newSubMenu still gets the class open and I cant figure out why.
The goal I am trying to achieve, is to NOT apply the class open until the animation is complete.
From the documentation:
When .stop() is called on an element, the currently-running animation (if any) is immediately stopped. … Callback functions are not called.
Callback functions are called if the third argument to stop() is true.
In the code you provide, though, the callback will run because you're stopping already running animations, not the slideToggle() animation which has yet to run when stop() is called.
Here is a working example showing the callback being stopped.
.stop() can be used to stop currently running animations. Once the animation has been completed the callback will be executed. In order to stop the current animation and avoid the callback being called you need to do something like this;
newSubMenu.mouseover(function(){
newSubMenu.slideToggle(250, function(){
$(this).css('visibility', 'visible').addClass('open');
});
}).dblclick(function(){
// this will stop the execution of the .slideToggle animation
// whitch will prevent the callback from being executed
newSubMenu.stop();
});
jsFiddle example
To see why this happens, you have to understand, what toggle does.
Everytime you click, the slideToggle gets itself the information to slideDown or slideUp.
The conclusion is: everytime the toggle is complete, your function will be called and your newSubMenu gets the visibility:visible style, plus the class "open" if it doesn't exist.
Click-> Stop all animations on element -> toggle slide -> call/excecute function
jQuery has added an "always" callback in version 1.8:
always
Type: Function( Promise animation, Boolean jumpedToEnd )
A function to be called when the animation completes or stops without
completing (its Promise object is either resolved or rejected).
(version added: 1.8)
URL: http://api.jquery.com/animate/
This will be fired always, if an animation is regularly done or if you interupt it with stop().
I'm trying to animate using jQuery but on IE7/8/9 it's not working before I show the element.
function callback() {
$('#content').animate([...]);
[...]
}
$('#content').hide();
[...]
$('#content').show();
callback();
It only works to me when a do setTimeout(function() { callback(); }, 300);, maybe I need to wait the IE to recognize the element that has been shown, before execute the callback. What is the problem here?
You need to wait for the element to exist within the page before you can select it with jQuery.
wrap your script with:
jQuery(function($){
//your code here
});
It's a shortcut for the document.ready event listener.
Since JS is single-threaded just because you call show() doesn't mean it's actually showing; you need to return control to the parent to allow it to draw and update the DOM before that happens. setTimeout allows your JS to yield to the parent, making it's updates before you continue with execution. setTimeout with 0 will most likely also work.
Let's say I've called $element.fadeIn(200). 100 ms later, something happens on that page and I want to interrupt that fade and immediately fadeOut(). How can I do this?
If you call calling $element.fadeIn(200).fadeOut(0), the fadeOut() only happens after the fadeIn() has finished.
Also, is there a way I can examine $element to determine if a fadeIn() or fadeOut() is running? Does $element have any .data() member that changes?
stop() will only remove animations that are not executed yet.
use stop(true, true) to interrupt and remove the current animation too!
You will get smooth fadeIn/Out effect by clearing queue but not jumping to the end, using .stop(true,false), but please notice that as FadeIn can be interrupted this way, FadeOut can not. I reported it as a bug like years ago, but noone cared. FadeIn only works if the object is hidden. But there is workaround... use FadeTo instead - it works on hidden as well as partially faded objects:
$('.a').hover(function(){
$('.b').stop(true,false).fadeTo(3000,1); // <- fadeTo(), not FadeIn() (!!!)
},function(){
$('.b').stop(true,false).fadeOut(3000);
});
Here's how it works: http://jsfiddle.net/dJEmB/
AFAIK fadeIn and fadeOut run synchronously, so no, I do not think you can interrupt them while they are running. You would have to wait until it is done executing.
If you call the stop method on the element it will stop all animations. The reason the fadeOut call in your example isn't called until after fadeIn is because animations are executed in a queue-like fashion.
You can use the stop() function to interrupt any animation that takes place during that particular moment. Let me know if this works.
Its always a good practice to keep functions that deal with an animation etc inside the function's callback. You can tell if the fadeIn() has finished by doing your function from within its callback, like:
$element.fadeIn(200, function(){
//do callback
});
If that is not possible then you can declare a variable outside the function. Say, var elmFadeInRunning = false. Change it to true right before you call fadeIn and change it back to false in the callback of the fadeIn. That way you can know if its still running if elmFadeInRunning == true.
Another working example
<div id="fadediv">Yay, I like to fade</div>
<button id="stopdatfade" >Stop that fade!</button>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
<script>
(function($){
currentfade = $("#fadediv").fadeOut(5000).fadeIn(5000).fadeOut(5000).fadeIn(5000);
$('#stopdatfade').on('click', function () {
if (typeof currentfade !== 'undefined') {
currentfade.stop(true, true);
}
});
})(jQuery);
</script>
Adding .stop(true,true) prior to the fadeIn will interrupt any current animations and execute the fadeIn immediately.
$('.saved').stop(true, true).fadeIn().delay(400).fadeOut(4000);
Try taking animation out from queue.
$('...').fadeIn(200).dequeue().fadeOut(0);
http://api.jquery.com/queue/
http://api.jquery.com/dequeue/
My method fades a div box out and has a callback that calls a method... like this:
function closeWindow(windowIdPrefix, speed) {
$("#" + windowIdPrefix + "_ViewPanel").fadeOut(speed,
function() {
resetWindow(windowIdPrefix);
numWindowsOpen--;
}
);
}
function resetWindow(windowIdPrefix) {
alert("resetting window");
}
When this executes (onClick of a button) I have an alert in resetWindow to see how many times it executes.
It seems to execute forever, but I haven't sat there long enough closing the alert windows to find out.
I did some research and read in the Jquery Documentation:
callback (Optional) Function
A function to be executed whenever the animation completes, executes once for each element animated against.
So I was wondering, even though I'm only fading out 1 div, does it count as 1.. plus 1 for each child element the div has?
Technically they are being animated because the inner elements are being faded out with the outer div, but if you watch the javascript in firebug only the outer div I'm fading out gets it's opacity/display changed.
If this is what's happening, how do I make sure the callback only gets executed once?
Edit: It was the line numWindowsOpen--; I hadn't defined numWindowsOpen before the function so for some reason that was making the call happen multiple times... Can anyone explain why this was happening?
The callback should only be invoked once for each element that matched the selector. Do you see multiple alerts when putting an alert message directly in the callback?
function() {
alert('Test');
resetWindow(windowIdPrefix);
numWindowsOpen--;
}
Problem was that numWindowsOpen wasn't declared before it was decremented there... Good reminder to make sure you look for simple things like that before going to more complicated tihngs.