I am using scriptaculous to perform a slidedown effect using the following code:
Effect.SlideDown('dom_element_id');
I then hide the button which initiates this effect using:
$('button_id').hide();
The issue is that the button is hidden before the animation effect is complete, I would like it to hide after the animation effect is complete. I could not find a callback parameter for Effect.SlideDown.
You can pass the afterFinish option to pass a callback to be run after the effect has been completed.
Effect.SlideDown('dom_element_id', { afterFinish: function () {$('button_id').hide(); } } );
EDIT
Note that beforeFinish, afterFinish, beforeSetup, afterSetup, beforeUpdate and afterUpdate options can be used for any effects as they are part of Effect.Base.
Also see the official docs here.
Related
I am currently trying to make my own Javascript notice system using Javascript and CSS3 and utilising it's animations.
I want to detect when the element transition has finished so I can remove the element from the DOM.
The animation is called animate-out which is a custom one I made within CSS3 using only 2 keyframes.
I have a close button on the notice, which when I click it adds a class of is-closed. Once is-closed animation has finished I want to be able to detect this, which I am currently trying to find out via using a console.log('finished'); however it seems as though the event is not being fired at all.
Here is my current code:
const close = document.querySelector('.close');
const notice = document.querySelector('.notice')
close.addEventListener('click', function() {
notice.classList.add('is-closed');
});
notice.addEventListener('webkitTransitionEnd', function() {
console.log('finished');
});
notice.addEventListener('transitionend', function() {
console.log('finished');
});
If you are using keyframes then you are using animation and not transitions.
The relevant event is animationend
Also read Using animation events
I have a page that uses
$(id).show("highlight", {}, 2000);
to highlight an element when I start a ajax request, that might fail so that I want to use something like
$(id).show("highlight", {color: "#FF0000"}, 2000);
in the error handler. The problem is that if the first highlight haven't finished, the second is placed in a queue and wont run until the first is ready. Hence the question: Can I somehow stop the first effect?
I listed this as a comment for the accepted answer, but I thought it would be a good idea to post it as a standalone answer as it seems to be helping some people having problems with .stop()
FYI - I was looking for this answer as well (trying to stop a Pulsate Effect), but I did have a .stop() in my code.
After reviewing the docs, I needed .stop(true, true)
From the jQuery docs:
http://docs.jquery.com/Effects/stop
Stop the currently-running animation on the matched elements....
When .stop() is called on an element, the currently-running animation (if any) is immediately stopped. If, for instance, an element is being hidden with .slideUp() when .stop() is called, the element will now still be displayed, but will be a fraction of its previous height. Callback functions are not called.
If more than one animation method is called on the same element, the later animations are placed in the effects queue for the element. These animations will not begin until the first one completes. When .stop() is called, the next animation in the queue begins immediately. If the clearQueue parameter is provided with a value of true, then the rest of the animations in the queue are removed and never run.
If the jumpToEnd argument is provided with a value of true, the current animation stops, but the element is immediately given its target values for each CSS property. In our above .slideUp() example, the element would be immediately hidden. The callback function is then immediately called, if provided...
.stop(true,true) will freeze the effect so if it's invisible at the time then it remains invisible. This could be a problem if you are using the pulsate effect.
$('#identifier').effect("pulsate", {times:5}, 1000);
To get around this I added
$('#identifier').stop(true, true).effect("pulsate", { times: 1 }, 1);
In my case, using below code does not work and keep your opacity value remain:
$('#identifier').stop(true, true).effect("pulsate", { times: 1 }, 1);
For me just remove opacity are working:
$('#identifier').stop(true, true).css('opacity','');
scenario:
An animation can be called multiple times.
The animation is called by another event such as a click event.
The animation should not fire until it is sure that all other animation events involving this structure are complete.
example: http://jsfiddle.net/xo6ngbfz/
jQuery( document ).ready(function() {
console.log('run');
jQuery("#animation-object").bind("fire-hide", function () {
jQuery(this).toggle();
});
jQuery('#element').on('click', function () {
console.log('click');
jQuery('*').trigger("fire-hide");
});
});
Further understanding:
This is a very simple animation; but say for instance someone had a set of tiles. These tiles slide up and down on the screen after a link has been clicked on.
If we do not wait for all animations to be complete, the slide effect could stop half way through the animation and revert to whatever animation was last clicked.
I did an example with your code. I hope it could be useful for you!
The key was use a counter for total animations you have and pass a function as a callback for each one:
jQuery(this).toggle("slow", animationFinished);
You shoud do it for each jquery function you want to it notify you that it was finished.
(when function not accept callback, it is enough call animationFinished() after it, see line 14 of the example).
When the counter of animations has finished is equal to the total animation counter, then a function is called and the counter is reseted.
It is no the best way to do it, because each time you add an animation, you have to modify the totalAnimations counter, but at least is an option for now.
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();
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().