Run jquery function between delay() function - javascript

after successful ajax call I have jquery open toast function:
function successMessage() {
$("#toast_success").show("slow").delay(3000).hide("slow");
}
Some people might want to close that toast before 3s [ delay(3000) ]:
$(".toast_close").on('click', function() {
$("#toast_success").hide("slow");
});
Unfortunately on click event do not work, message dissapears after 3seconds, and thats it. Any suggestions how to make work "$(".toast_close").on('click', function()" ?

The issue is because the delay() call is still on the animation queue. The hide() method, when called with a time argument, will also use the animation queue. As such, the hide() is blocked until delay() ends.
To fix this, either use hide() with no argument, although this may be jarring in your UI, or call stop(true) to clear the animation queue before you call hide():
$(".toast_close").on('click', function() {
$("#toast_success").stop(true).hide("slow");
});

The .delay() method allows us to delay the execution of functions that follow it in the queue. SO we need to stop the animation queue. For Stoping the animation we use stop(true) or stop() method and then hide slowly.
$(".toast_close").on('click',function(){
$("#toast_success").stop().hide("slow");
});

Related

jQuery + Stop + Callback Functions

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().

Trigger a delayed hover event with jQuery

I'm trying to trigger a delayed hover event:
$(".graphic").delay(500).trigger('mouseover').trigger('mouseout');
But the delay is being ignored.
Any ideas?
delay() only affects the animation queue, but trigger() is synchronous. You can use queue() to schedule a function triggering the events after the delay:
$(".graphic").delay(500).queue(function(next) {
$(this).trigger("mouseover").trigger("mouseout");
next();
});
The .delay() method is best for delaying between queued jQuery effects.
To delay the initial effect, use setTimeout() function. By the way, you could use mouseover() instead of trigger('mouseover')
setTimeout(function () {
$(".graphic").mouseover().mouseout();
}, 500);
The jQuery API says:
Only subsequent events in a queue are delayed; for example this will not delay the no-arguments forms of .show() or .hide() which do not use the effects queue.
Maybe you can set a timer, that will trigger mouseover/out after 500 ms using Windows.setTimeout

JQuery chaining actions, works..but CSS doesn't wait it's turn?

so i have something like so (below), everything works in turn (it's hidden at the start, then you see it slide down, waits 2 seconds, and slides back up) but the .css action takes place immediately, even though it's after the 2 second delay. Just wondering why this is.
$('p:first')
.hide()
.slideDown('slow')
.delay(2000)
.css({"background-color":"#ff4"})
.slideUp('slow')
});
EDIT NEW CODE: I have changed my code to this: which doesn't seem to slideUp anymore.. (as I want it to change to yellow right before sliding up)
$('p:first')
.hide()
.slideDown('slow')
.delay(2000, function(){
$(this).css({"background-color": "#ff4"})
})
.slideUp('slow')
});
That's because delay() only affects the animation queue. Method chaining occurs as soon as the previous call returns, so css() (which is not an animation) ends up being called too soon.
You can pass a callback function to slideUp(), and it will be called when the animation is complete:
$("p:first").hide()
.slideDown("slow")
.delay(2000)
.slideUp("slow", function() {
$(this).css("background-color", "#ff4");
});
EDIT: You're trying to pass a callback to delay() in your second code snippet, but that method does not officially support such an argument (it still gets called, though, which is interesting). However, doing that breaks the animation callback chain, as you can see, since slideUp() is never called.
In this situation, you can inject your own function in the animation queue, using the aptly-named queue() and dequeue() methods:
$("p:first").hide()
.slideDown("slow")
.delay(2000)
.queue(function() {
$(this).css("background-color", "#ff4")
.dequeue();
}).slideUp("slow");
The ".css()" call is a synchronous operation, but all the others are animations. The animation functions all return immediately after queueing up the operation for later.
There's a way to queue up your own code in the animation queue, I think, but I won't type in a guess; I'll make a quick check of the documentation.
edit — ok what you'd do is this:
$('p:first')
.hide()
.slideDown('slow')
.delay(2000)
.queue(function(next)
$(this).css({"background-color":"#ff4"});
next();
})
.slideUp('slow')
});
Seems like using the callbacks as others suggested should work too.
Change the css in the callback
$('p:first')
.hide()
.slideDown('slow')
.delay(2000)
.slideUp('slow',function(){
$(this).css({backgroundColor:"#ff4"})
})

jQuery: Delayed fade unless clicked?

So I currently I have this:
$('#message_notice').click(function(){
$(this).fadeOut('slow');
});
$('#message_notice').delay(8000).fadeOut('slow');
What I'm ultimately trying to do is if a message is clicked, then go ahead and fade it out. Otherwise, in X seconds, fade it out automatically.
I can do one or the other, but if I have both (as in my example) then the on-click doesn't work (just the delayed fade).
I'm using jQuery 1.4.4.
You need to call .stop(true) in the click handler to cancel the delay() that you put in the queue.
New code should look like
$('#message_notice').click(function(){
$(this).stop(true).fadeOut('slow');
});
$('#message_notice').delay(8000).fadeOut('slow');
That's because when you run
$('#message_notice').delay(8000).fadeOut('slow');
you are creating an animation queue to which your
$('#message_notice').fadeOut('slow');
gets appended if someone clicks.
For a solution see the answer by SLaks who posted it faster than I could finish writing...

jQuery: interrupting fadeIn()/fadeOut()

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/

Categories