jQuery 动画线程 - 竞争条件?
jQuery Animation Thread - Race Condition?
我想要的
我希望用户能够单击此 div,让动画调整文本框 div 的大小。一旦用户再次点击它,动画将执行相同的顺序但相反。
我有什么
http://jsfiddle.net/fenderistic/phx09dw7/15/
问题
动画序列工作正常,直到用户开始快速点击它。动画序列会搞砸,因为我依赖于动画时 div 的当前高度,我相信这两个动画序列会同时发生。
我试过的
如您所见,我尝试设置一个 animationrunning
变量来防止动画在最后一个动画尚未完成时开始。
var animationrunning = false;
$("div.archived_field").click(function () {
var me = $(this);
var check = me.find("input:checkbox");
check.trigger('click');
})
$("input:checkbox").click(function (event) {
if(!animationrunning){
animationrunning=true;
event.stopPropagation();
var me = $(this).parent("div.archived_field");
var id = me.data("field")
var check = me.find("input:checkbox");
var date = me.find("input:text");
if (check.is(":checked")) {
me.animate({
height: (me.height() + 52) + "px"
}, 100, function () {
date.show(100, function () {
animationrunning = false;
});
})
//remove from lists to move forward
} else {
date.hide(100, function () {
me.animate({
height: (me.height() - 52) + "px"
}, 100, function () {
animationrunning = false;
})
});
//add to lists to move forward
}
}
});
$("input[type=text]#archive_dates").click(function (event) {
event.stopPropagation();
});
我觉得是什么问题
我认为正在发生某种竞争条件,并且线程没有提取 animationrunning
的有效值 - 因此允许动画同时 运行。
还有
我玩过不依赖于 div 在动画时的高度(这减少了视觉错误),但我仍然有复选框没有被选中,当它应该反之亦然。
如有任何帮助或反馈,我们将不胜感激。
我认为你的 animationrunning
标志有效(无竞争条件),但问题是当动画 [=27] 时用户仍然可以单击复选框(或 div) =].当用户这样做时,复选框的状态与动画元素的状态不同步。
您可以在动画 运行.
时禁用复选框,而不是标志
$("input:checkbox").click(function (event) {
event.stopPropagation();
var $checkbox = $(this);
$checkbox.attr('disabled', true);
var me = $(this).parent("div.archived_field");
var id = me.data("field")
var check = me.find("input:checkbox");
var date = me.find("input:text");
if (check.is(":checked")) {
me.animate({
height: (me.height() + 52) + "px"
}, 1001, function () {
date.show(1001, function () {
$checkbox.attr('disabled', false);
});
})
//remove from lists to move forward
} else {
date.hide(1001, function () {
me.animate({
height: (me.height() - 52) + "px"
}, 1001, function () {
$checkbox.attr('disabled', false);
})
});
//add to lists to move forward
}
});
另一个解决方案是在向另一个方向设置动画之前停止动画。这在您的情况下会很困难,因为您正在为两个元素设置动画。如果你只制作一个动画,那就更容易了。
此 jsfiddle 展示了如何使用 .stop()
方法停止动画,但代码已更改,因此只有一个元素正在播放动画。文本框的hide/show不再有动画。
我想要的
我希望用户能够单击此 div,让动画调整文本框 div 的大小。一旦用户再次点击它,动画将执行相同的顺序但相反。
我有什么
http://jsfiddle.net/fenderistic/phx09dw7/15/
问题
动画序列工作正常,直到用户开始快速点击它。动画序列会搞砸,因为我依赖于动画时 div 的当前高度,我相信这两个动画序列会同时发生。
我试过的
如您所见,我尝试设置一个 animationrunning
变量来防止动画在最后一个动画尚未完成时开始。
var animationrunning = false;
$("div.archived_field").click(function () {
var me = $(this);
var check = me.find("input:checkbox");
check.trigger('click');
})
$("input:checkbox").click(function (event) {
if(!animationrunning){
animationrunning=true;
event.stopPropagation();
var me = $(this).parent("div.archived_field");
var id = me.data("field")
var check = me.find("input:checkbox");
var date = me.find("input:text");
if (check.is(":checked")) {
me.animate({
height: (me.height() + 52) + "px"
}, 100, function () {
date.show(100, function () {
animationrunning = false;
});
})
//remove from lists to move forward
} else {
date.hide(100, function () {
me.animate({
height: (me.height() - 52) + "px"
}, 100, function () {
animationrunning = false;
})
});
//add to lists to move forward
}
}
});
$("input[type=text]#archive_dates").click(function (event) {
event.stopPropagation();
});
我觉得是什么问题
我认为正在发生某种竞争条件,并且线程没有提取 animationrunning
的有效值 - 因此允许动画同时 运行。
还有
我玩过不依赖于 div 在动画时的高度(这减少了视觉错误),但我仍然有复选框没有被选中,当它应该反之亦然。
如有任何帮助或反馈,我们将不胜感激。
我认为你的 animationrunning
标志有效(无竞争条件),但问题是当动画 [=27] 时用户仍然可以单击复选框(或 div) =].当用户这样做时,复选框的状态与动画元素的状态不同步。
您可以在动画 运行.
时禁用复选框,而不是标志$("input:checkbox").click(function (event) {
event.stopPropagation();
var $checkbox = $(this);
$checkbox.attr('disabled', true);
var me = $(this).parent("div.archived_field");
var id = me.data("field")
var check = me.find("input:checkbox");
var date = me.find("input:text");
if (check.is(":checked")) {
me.animate({
height: (me.height() + 52) + "px"
}, 1001, function () {
date.show(1001, function () {
$checkbox.attr('disabled', false);
});
})
//remove from lists to move forward
} else {
date.hide(1001, function () {
me.animate({
height: (me.height() - 52) + "px"
}, 1001, function () {
$checkbox.attr('disabled', false);
})
});
//add to lists to move forward
}
});
另一个解决方案是在向另一个方向设置动画之前停止动画。这在您的情况下会很困难,因为您正在为两个元素设置动画。如果你只制作一个动画,那就更容易了。
此 jsfiddle 展示了如何使用 .stop()
方法停止动画,但代码已更改,因此只有一个元素正在播放动画。文本框的hide/show不再有动画。