How does end() work for animate()?

1.2k Views Asked by At

I'm currently looking into chaining my jquery code. An element needs to ditch a border, animated. My solution: animate the borderWidth to zero and then remove the class:

$(".imgWrap", element).animate({ borderWidth: "0px" }).end()
    .removeClass("border");

animate() is supposed to return the wrapped element, but what I understand from the jQuery API, end() will return the object to its state before the call to .find.

.find is in the context of the example so I took the liberty to replace it with .animate. Alas, this does not work for me. The result of .end() is the result of .animate().

2

There are 2 best solutions below

0
On BEST ANSWER

Because you (now) have no find filter (or any other filter), end has nothing to undo. It has nothing to do with animate.

If you were to first select a container, then look within it for imgWrap, you could undo the filter:

$('.container').find('.imgWrap').animate({borderWidth: '0px'}).end();

The above will return the elements matching $('.container'), as the find is undone by end

What may be confusing things is that if you chain removeClass immediately after animate, removeClass will not wait for animate to finish so it will appear that there is no animation happening. You need to remove the class in the complete function of animate:

$(".imgWrap", element).animate({ borderWidth: "0px" }, function(){
    $(this).removeClass('border');
});
1
On

.end() returns the jQuery object to its state before .find()

i.e. if I do this:

$('div').find('.class').end()

then what's left after chaining is the result of $('div'). It doesn't change anything about the elements themselves.

The jQuery object returned by most jQuery methods not only contains the current matching elements, but also contains a stack of the results from previous chained calls.

Hence when you call .find() the previous list is still stored on that stack. Calling .end() just removes the last item from the stack.

To fix your actual problem (i.e. changing a style after the animation has finished) you need to put that change in a complete callback function parameter to .animate() itself.

$(".imgWrap", element)
   .animate({ borderWidth: "0px" }, function() {
       $(this).removeClass("border");
   });