Added enchancement for #1994 by adding two parameters to .stop() which give additional functionality. The first parameter clearQueue will clear the queue on the necessary DOM elements so all animation will stop. The second parameter will cause the currently playing animation to immediately complete including reseting original styles on show and hide and calling the callback function. If no parameters are passed it will work as it always did.
While adding unit testing I noticed the stop() unit test wasn't working correctly because the element was hidden so I fixed it and added more unit tests around the new functionality. I also added a cursor:pointer to the css (because for a long time I didn't know they were clickable).
This commit is contained in:
parent
37902e86b1
commit
5039a4bc5b
34
src/fx.js
34
src/fx.js
|
@ -146,14 +146,28 @@ jQuery.fn.extend({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
stop: function(){
|
stop: function(clearQueue, gotoEnd){
|
||||||
var timers = jQuery.timers;
|
var timers = jQuery.timers;
|
||||||
|
|
||||||
return this.each(function(){
|
if (clearQueue)
|
||||||
for ( var i = 0; i < timers.length; i++ )
|
this.queue([]);
|
||||||
if ( timers[i].elem == this )
|
|
||||||
timers.splice(i--, 1);
|
this.each(function(){
|
||||||
}).dequeue();
|
// go in reverse order so anything added to the queue during the loop is ignored
|
||||||
|
for ( var i = timers.length - 1; i >= 0; i-- )
|
||||||
|
if ( timers[i].elem == this ) {
|
||||||
|
if (gotoEnd)
|
||||||
|
// force the next step to be the last
|
||||||
|
timers[i](true);
|
||||||
|
timers.splice(i, 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// start the next in the queue if the last step wasn't forced
|
||||||
|
if (!gotoEnd)
|
||||||
|
this.dequeue();
|
||||||
|
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -269,8 +283,8 @@ jQuery.fx.prototype = {
|
||||||
this.update();
|
this.update();
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
function t(){
|
function t(gotoEnd){
|
||||||
return self.step();
|
return self.step(gotoEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
t.elem = this.elem;
|
t.elem = this.elem;
|
||||||
|
@ -322,10 +336,10 @@ jQuery.fx.prototype = {
|
||||||
},
|
},
|
||||||
|
|
||||||
// Each step of an animation
|
// Each step of an animation
|
||||||
step: function(){
|
step: function(gotoEnd){
|
||||||
var t = (new Date()).getTime();
|
var t = (new Date()).getTime();
|
||||||
|
|
||||||
if ( t > this.options.duration + this.startTime ) {
|
if ( gotoEnd || t > this.options.duration + this.startTime ) {
|
||||||
this.now = this.end;
|
this.now = this.end;
|
||||||
this.pos = this.state = 1;
|
this.pos = this.state = 1;
|
||||||
this.update();
|
this.update();
|
||||||
|
|
|
@ -11,6 +11,8 @@ p.result { margin-left: 1em; }
|
||||||
h2.pass { background-color: green; }
|
h2.pass { background-color: green; }
|
||||||
h2.fail { background-color: red; }
|
h2.fail { background-color: red; }
|
||||||
|
|
||||||
|
ol#tests > li > strong { cursor:pointer; }
|
||||||
|
|
||||||
div#fx-tests h4 {
|
div#fx-tests h4 {
|
||||||
background: red;
|
background: red;
|
||||||
}
|
}
|
||||||
|
|
106
test/unit/fx.js
106
test/unit/fx.js
|
@ -54,21 +54,101 @@ test("queue() defaults to 'fx' type", function () {
|
||||||
test("stop()", function() {
|
test("stop()", function() {
|
||||||
expect(3);
|
expect(3);
|
||||||
stop();
|
stop();
|
||||||
reset();
|
|
||||||
|
|
||||||
var foo = $("#foo")[0];
|
var $foo = $("#nothiddendiv");
|
||||||
var h = foo.style.height;
|
var w = 0;
|
||||||
|
$foo.hide().width(200).width();
|
||||||
|
|
||||||
$("#foo").slideUp(1000);
|
$foo.animate({ width:'show' }, 1000);
|
||||||
setTimeout(function(){
|
setTimeout(function(){
|
||||||
var nh = foo.style.height;
|
var nw = $foo.width();
|
||||||
ok( nh != h, "An animation occurred " + nh + " " + h );
|
ok( nw != w, "An animation occurred " + nw + "px " + w + "px");
|
||||||
$("#foo").stop();
|
$foo.stop();
|
||||||
|
|
||||||
nh = foo.style.height;
|
nw = $foo.width();
|
||||||
ok( nh != h, "Stop didn't reset the animation " + nh + " " + h );
|
ok( nw != w, "Stop didn't reset the animation " + nw + "px " + w + "px");
|
||||||
setTimeout(function(){
|
setTimeout(function(){
|
||||||
equals( nh, foo.style.height, "The animation didn't continue" );
|
equals( nw, $foo.width(), "The animation didn't continue" );
|
||||||
|
start();
|
||||||
|
}, 100);
|
||||||
|
}, 100);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("stop() - several in queue", function() {
|
||||||
|
expect(4);
|
||||||
|
stop();
|
||||||
|
|
||||||
|
var $foo = $("#nothiddendiv");
|
||||||
|
var w = 0;
|
||||||
|
$foo.hide().width(200).width();
|
||||||
|
|
||||||
|
$foo.animate({ width:'show' }, 1000);
|
||||||
|
$foo.animate({ width:'hide' }, 1000);
|
||||||
|
$foo.animate({ width:'show' }, 1000);
|
||||||
|
setTimeout(function(){
|
||||||
|
equals( $foo.queue().length, 3, "All 3 still in the queue" );
|
||||||
|
var nw = $foo.width();
|
||||||
|
ok( nw != w, "An animation occurred " + nw + "px " + w + "px");
|
||||||
|
$foo.stop();
|
||||||
|
|
||||||
|
nw = $foo.width();
|
||||||
|
ok( nw != w, "Stop didn't reset the animation " + nw + "px " + w + "px");
|
||||||
|
equals( $foo.queue().length, 2, "The next animation continued" );
|
||||||
|
$foo.stop(true);
|
||||||
|
start();
|
||||||
|
}, 100);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("stop(clearQueue)", function() {
|
||||||
|
expect(4);
|
||||||
|
stop();
|
||||||
|
|
||||||
|
var $foo = $("#nothiddendiv");
|
||||||
|
var w = 0;
|
||||||
|
$foo.hide().width(200).width();
|
||||||
|
|
||||||
|
$foo.animate({ width:'show' }, 1000);
|
||||||
|
$foo.animate({ width:'hide' }, 1000);
|
||||||
|
$foo.animate({ width:'show' }, 1000);
|
||||||
|
setTimeout(function(){
|
||||||
|
var nw = $foo.width();
|
||||||
|
ok( nw != w, "An animation occurred " + nw + "px " + w + "px");
|
||||||
|
$foo.stop(true);
|
||||||
|
|
||||||
|
nw = $foo.width();
|
||||||
|
ok( nw != w, "Stop didn't reset the animation " + nw + "px " + w + "px");
|
||||||
|
|
||||||
|
equals( $foo.queue().length, 0, "The animation queue was cleared" );
|
||||||
|
setTimeout(function(){
|
||||||
|
equals( nw, $foo.width(), "The animation didn't continue" );
|
||||||
|
start();
|
||||||
|
}, 100);
|
||||||
|
}, 100);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("stop(clearQueue, gotoEnd)", function() {
|
||||||
|
expect(3);
|
||||||
|
stop();
|
||||||
|
|
||||||
|
var $foo = $("#nothiddendiv");
|
||||||
|
var w = 0;
|
||||||
|
$foo.hide().width(200).width();
|
||||||
|
|
||||||
|
$foo.animate({ width:'show' }, 1000);
|
||||||
|
$foo.animate({ width:'hide' }, 1000);
|
||||||
|
$foo.animate({ width:'show' }, 1000);
|
||||||
|
$foo.animate({ width:'hide' }, 1000);
|
||||||
|
setTimeout(function(){
|
||||||
|
var nw = $foo.width();
|
||||||
|
ok( nw != w, "An animation occurred " + nw + "px " + w + "px");
|
||||||
|
$foo.stop(false, true);
|
||||||
|
|
||||||
|
nw = $foo.width();
|
||||||
|
equals( nw, 200, "Stop() reset the animation" );
|
||||||
|
|
||||||
|
setTimeout(function(){
|
||||||
|
equals( $foo.queue().length, 3, "The next animation continued" );
|
||||||
|
$foo.stop(true);
|
||||||
start();
|
start();
|
||||||
}, 100);
|
}, 100);
|
||||||
}, 100);
|
}, 100);
|
||||||
|
@ -77,11 +157,11 @@ test("stop()", function() {
|
||||||
test("toggle()", function() {
|
test("toggle()", function() {
|
||||||
expect(3);
|
expect(3);
|
||||||
var x = $("#foo");
|
var x = $("#foo");
|
||||||
ok( x.is(":visible") );
|
ok( x.is(":visible"), "is visible" );
|
||||||
x.toggle();
|
x.toggle();
|
||||||
ok( x.is(":hidden") );
|
ok( x.is(":hidden"), "is hidden" );
|
||||||
x.toggle();
|
x.toggle();
|
||||||
ok( x.is(":visible") );
|
ok( x.is(":visible"), "is visible again" );
|
||||||
});
|
});
|
||||||
|
|
||||||
var visible = {
|
var visible = {
|
||||||
|
|
Loading…
Reference in a new issue