Problems with removing elements in jQuery - javascript

I am attempting to remove an object from a page with jQuery. I also want to animate the removal. The goal is to make the element fadeOut(), wait a second, then remove(). But it seems to refuse to wait to remove the element, even when I use it in a setTimeout() function. How can I make an element fadeOut(), and then remove() it?
$("button").click(function() {
$(this).fadeOut();
setTimeout(function() { $(this).remove();}, 1000);
});

Read manual carefully:
http://api.jquery.com/fadeOut/
The fadeOut() method has a callback that is invoked after the fadeOut completes. To use it:
$("button").click(function() {
$(this).fadeOut(function() { $(this).remove();});
});
There should be no reason to wait one second after the fadeOut completes, before removing the element, because the element will be invisible when it is removed.

In your timeout function, this isn't what you think it is - it's actually the global window object.
In any event (no pun intended) you should use a "completion callback":
$("button").click(function() {
$(this).fadeOut('slow', function() {
$(this).remove();
});
});
Never, ever, mix setTimeout and the animation queue. It's fine to interleave the two, i.e having a completion callback start a timer, or having a timer starting an animation, but it's never OK to assume that you can start both a 1000ms animation and a 1000ms timer and have them complete at the same time.
EDIT fixed code - no need for self in a completion callback, I was still thinking about setTimeout and this when I wrote that!

$('button').click(function(){
$(this).fadeOut(function(){$(this).remove()});
});​
DEMO

Why not just use the callback of fadeout?
$("button").click(function() {
$(this).fadeOut(function(){$(this).remove();});
});

try this one, maybe it helps:
$("button").click(function() {
(function(that) {
that.fadeOut();
setTimeout(function() {
that.remove();
}, 1000);
})($(this));
});

Related

Wait for animation to complete before continuing in jQuery

Is there anyway to wait for a jQuery animation to finish before proceeding with another command?
For example, I want to fade out/slide up an element, change some items within the element and then fade them back in/slide back down.
If I put the statements one after another, you can see the items change before the animation completes.
$('#item').fadeOut();
$('#item').html('Changed item');
$('#item').fadeIn();
Thanks.
You can pass callback in fadeIn/fadeOut. jQuery docs
$('#item').fadeOut('slow', function(){
$('#item').html('Changed item');
$('#item').fadeIn();
});
You can either use the callback method which gets called from .fadeOut, like
$('#item').fadeOut('fast', function() {
$(this).html('Changed item').fadeIn();
});
or use the underlaying Deferred object
$('#item').fadeOut('slow').promise().done(function() {
$(this).html('Changed item').fadeIn();
});
Pass a callback function to fadeOut.
$("#item").fadeOut(function() {
$(this).html("changed").fadeIn();
});
This is the sort of thing you'll learn in a basic jQuery tutorial.
$('#item').fadeOut('slow', function() { // do your stuff here });
For more info: http://docs.jquery.com/Effects/fadeOut#speedcallback

jQuery stop(true, true) to jump to end of all animations in queue

I have been using jQuery's stop(true, true) method to clear running animations so the next one starts immediately. I noticed that the first parameter, clearQueue, clears the entire animation queue but the second parameter, jumpToEnd, only jumps to the end of the currently running animation and not the ones that were removed from the queue. Is there a way to have it clear and jump to the end of all queued animations?
I've ended up chaining a few stop(false, true) calls instead, but this will only handle 3 queued animations, for example.
$(this)
.stop(false, true)
.stop(false, true)
.stop(false, true)
.addClass('hover', 200);
Edit:
I ended up adding my own method, stopAll, as per Ates Goral's answer:
$.fn.extend({ stopAll: function () {
while (this.queue().length > 0)
this.stop(false, true);
return this;
} });
$(this).stopAll().addClass('hover', 200);
I hope someone else finds this useful.
Chaining multiple stop(false, true) makes sense. Instead of hard-coding a fixed number of chained calls, you could check the queue length:
while ($(this).queue().length) {
$(this).stop(false, true);
}
Demo: http://jsfiddle.net/AB33X/
jQuery 1.9 introduced the .finish() method, which achieves exactly that.
I also notice from the documentation of the .finish() method in jQuery 1.9 that
Animations may be stopped globally by setting the property $.fx.off
to true. When this is done, all animation methods will immediately
set elements to their final state when called, rather than displaying an effect.
There is also a nice demo of the various methods on the .finish() documentation page.
Test for presence of class (set upon hover and removed on mouseOut animate callback) before staring new animation. When new animation does start, dequeue.
$("div").hover(function(){
if (!$(this).hasClass('animated')) {
$(this).dequeue().stop().animate({ width: "200px" });
}
}, function() {
$(this).addClass('animated').animate({ width: "100px" }, "normal", "linear", function() {
$(this).removeClass('animated').dequeue();
});
});

jQuery effects combination

I want to apply highlight and remove effects to the same dom. One after the other. Unfortunately the highlight effect is not visible as the remove gets triggered immediately after.
Any idea to delay the remove action?
$("#<%= dom_id(#stock) %>").effect("highlight", {}, 4000)
$("#<%= dom_id(#stock) %>").remove()
Problem is, .remove() can't be delayed. It is one of those functions that triggers right away, meaning .delay() does nothing.
However, JavaScript's setTimeout() function will:
$('#g').click(function(){
$("#hi").hide("highlight", {}, 4000)
setTimeout('$("#<%= dom_id(#stock) %>").remove();', 4100)
});
Here's an example of this on jsFiddle.
.effect() have callback argument that will get called after effect finishes. See effect demo.
$("#<%= dom_id(#stock) %>").effect("highlight", {}, 4000, function() {
$("#<%= dom_id(#stock) %>").remove();
});
Is effect a jQuery PlugIn ? I cant find any documentation of that function on the jQuery Site.
Use jQuery Animate because you got a callback after your animation is done.
$("#<%= dom_id(#stock) %>").animate({
opacity: 0.25,
}, 4000, function() {
// Animation complete.
$("#<%= dom_id(#stock) %>").remove();
});
Update
like Shawn31313 said
effect(..)
is part of jQuery UI and this function also supports "callbacks" after the effect is done.
jQuery UI Effect
hope this helps

How to pause execution of javascript till jquery fade finishes

I want to do something like this
Fadein a div that covers some other div
change contents of that some other div
fadeout covering div and reveal that some other div below it.
Here is a code for that:
$pH('#coveringDiv').fadeIn(300);
//want to start doing something now, but only after above fadeIn finishes
adContainer = $pH(currAdBubble).find('.mcc');
$pH(adContainer).empty().html("some html");
$pH('.phAdScroller').attr('kw',keyword);
setTimeout("$pH('#coveringDiv').fadeOut(500);",300);
but what happens is, fadeIn and code written after that start together. i want code below fadeIn to start only after fadeIn finishes. I tried an empty setTimeout, but that didn't help as well. It would be too weird to put that code in a function and call it in setTimeout() as there will be a need to pass many arguments to that function. So how to achieve this ?
fadeIn takes a callback function that will execute after the fadeIn is complete:
$pH('#coveringDiv').fadeIn(300, function () {
//want to start doing something now, but only after above fadeIn finishes
adContainer = $pH(currAdBubble).find('.mcc');
$pH(adContainer).empty().html("some html");
$pH('.phAdScroller').attr('kw',keyword);
setTimeout("$pH('#coveringDiv').fadeOut(500);",300);
});
http://api.jquery.com/fadeIn/
Most timed functions in jquery support a callback, which gets called when the timed action completes. So...
$pH('#coveringDiv').fadeIn(, 300, function() {
... code to execute after the fade completes ...
});
Try this:
$pH('#coveringDiv').fadeIn(300, function() {
adContainer = $pH(currAdBubble).find('.mcc');
$pH(adContainer).empty().html("some html");
$pH('.phAdScroller').attr('kw',keyword);
setTimeout("$pH('#coveringDiv').fadeOut(500);",300);
});
The 2nd argument of fadeIn is a callback thats called when the animation completes, so;
$pH('#coveringDiv').fadeIn(300, anotherFuncName);
or
$pH('#coveringDiv').fadeIn(300, function() {
// code here
});
Add a pause for 500 seconds. or a loop countdown.

if the hide() jquery animate function set after animate(),it doesn't work?

First I have a animate a iframe which id is "test"
<iframe id="test" src=""></iframe>
then I want animate it and hide it ,make a close effect like in MacOS:
$('#test').animate({
'width':0,
'height':0,
'top':$('input').offset().top,
'left':$('input').offset().left
},function(){
//$(this).hide();
}).hide();
but it seems the iframe can not be hide.However,if I write it in the callback function that in animate,which is the annotated code above.It could work again.
Here is online case
So I wonder why the hide() after animate() doesn't work?Do I miss something ?
To answer your question, the call to .hide() is performed immediately after the call to .animate(), so the .hide() invocation actually takes place before the animation completes, (.animate() runs asynchronously) - this is why jQuery provides the callback function to you so you can be notified of when the animation completes.
$('#test').animate({
'width':0,
'height':0,
'top':$('input').offset().top,
'left':$('input').offset().left
}, function(){
$("#test").hide();
});
Saved this for you on jsFiddle too
Set opacity to hide and it will work:
$('#mask').click(function () {
$('#mask').fadeOut(500);
$('#test').animate({
opacity: 'hide',
'top':$('input').offset().top,
'left':$('input').offset().left,
},3000);
});

Categories