jQuery动画线程 - 竞争条件?

时间:2015-02-17 17:17:51

标签: jquery animation

我想要什么

我希望用户能够单击此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的高度(这减少了视觉错误),但是当我假设&时,我仍然没有检查复选框。反之亦然。

非常感谢任何帮助或反馈。

1 个答案:

答案 0 :(得分:1)

我认为你的animationrunning标志有效(没有竞争条件),但问题是用户在动画运行时仍然可以点击复选框(或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

另一个解决方案是在向另一个方向制作动画之前停止动画。在你的情况下这很难,因为你是动画两个元素。如果你只动画一个,那就更容易了。

jsfiddle显示了如何使用.stop()方法停止动画,但代码已更改,因此只有一个元素被动画化。隐藏/显示文本框不再是动画。