Bug Tracker

Opened 9 years ago

Closed 9 years ago

Last modified 9 years ago

#7677 closed bug (invalid)

slideDown only does part of the animation if it was previously stopped

Reported by: matteosistisette Owned by:
Priority: undecided Milestone: 1.6
Component: unfiled Version: 1.4.4
Keywords: Cc:
Blocked by: Blocking:

Description

Try this:

1) start a slideDown() on a given element 2) call stop() on it before the animation is finished, when it is for example at 50% of completion 3) call slideUp() on the same element and let it finish. 4) call slideDown() again on the same element

Expected: it should perform the complete animation

Observed: it only slides to 50% in the example; in general to the point where it was stopped the first time

May be this applies to other animation as well, I've only tried slidedown

Change History (5)

comment:1 Changed 9 years ago by addyosmani

Owner: set to matteosistisette
Status: newpending

Thank you for submitting a ticket to the jQuery Bug Tracker!.

In order for us to investigate the issue you are experiencing further, please provide a reduced test case that reproduces this issue on jsFiddle.net.

Thanks!

comment:2 Changed 9 years ago by jitter

Owner: matteosistisette deleted
Status: pendingnew

comment:3 Changed 9 years ago by jitter

Resolution: invalid
Status: newclosed

I don't think there is any bug here, maybe just a misunderstanding on what happens when an element is animated and then stop() called before the animation is done. I think the behavior is best explained with a quick rundown based on this test case

  1. slideDown(): animation starts height:0px -> height:200px
  2. stop(): animation stops. element e.g. now has height:100px
  3. slideUp(): animation height:100px -> height:0px
  4. slideUp() done: display:none and height:100px are set
  5. slideDown() the 2nd: animation height:0px -> height:100px

Is there something wrong? No.

On the second call to slideDown() jQuery determines the starting value for the animation should be 0px the target value should be 100px. jQuery can't know here if the height value of 100px is a result from an earlier aborted animation or if you just did $(ele).css("height", 100).

If you want the 2nd slideDown() animation to go to 200px just remove one of the two uncommented $d.css("height", ""); lines in this test case. This resets the height and jQuery animates to the height given in the CSS rule.

Comment is rather on the long side but I hope I made myself clear and explained the behavior.

comment:4 Changed 9 years ago by matteosistisette

Well, the API lacks a clear specification of how high-level animation methods are supposed to behave when stopped. This kind of high-level animation methods such as show/hide, slideUp/slideDown, fadeIn/fadeOut are described in terms of two clearly defined "states". The description of the behavior seems to assume that the animation will always complete.

Even if you don't really need to "stop" the animation in order to freeze it, even if you only want to use the animations for the intended purpose of showing/hiding, a problem arises: what happens if you need to slideUp something that is sliding down? (think about the common case of a dropdown menu where you rollover and quickly rollout before the animation completes, and then quickly roll over again).

The way these methods work by default (i.e. if you simply call slideDown on an object that is currently sliding Up) is that the animations are queued. Anyway that is not always the desired behaviour: if you think about the above example of the dropdown menu, the resulting animation is a sequence of full ups and downs that may become long and annoying.

Often, very often indeed, when you need to trigger a slideUp on an element that is sliding Down (or viceversa), you prefer to stop the current animation and revert it. But then you would expect it to always go to one of the two well-defined states.

That doesn't seem to be possible. The last test case you posted ALMOST does that, but when you call slideDown after stopping, it jumps to the "down" state without animation.

comment:5 Changed 9 years ago by jitter

The animation methods behave exactly the same as the animate() method would (the are just convenience wrappers). They stop right away and leave the animated element in the current state. I think the behavior caused by stop() is well enough documented here http://api.jquery.com/stop/

If you need more control you probably shouldn't be using slideUp/slideDown and just use animate() directly. For the problem you described I suggest reading this comment on the jQuery forum which has several useful links on how to solve this.

Note: See TracTickets for help on using tickets.