如何在转移到下一行之前强制执行javascript?

时间:2014-08-27 09:27:37

标签: javascript jquery

我有几个过滤器显示或隐藏表中的表行,然后检查是否没有行可见,然后向表中添加一条消息,说明没有行。

这就是我尝试这样做的方法,但是失败了,也许我不知道JS执行行的方式,也许异步总是?

HTML

<input ID="cbFreshFruits" Checked="true" onclick="ToggleFruits(this)" />

脚本

function ToggleFruits(elm) {
    $target = $('#fruitTable tr[data-status="' + elm.id + '"]').filter(function () {
        var crates = $("#crateTable tr .selected").parent().map(function () {
            return $(this).data("crateID");
        }).get();
        return crates.indexOf($(this).data("crateID")) >= 0;
    });

    if (elm.checked) {
        $target.show("down");
    }
    else {
        $('#fruitTable tr[data-status="' + elm.id + '"]').hide("up");
    }

    CheckFruitExists();
}


function CheckFruitExists() {
    $("#NoFilteredFruits").hide();
    $("#fruitTable").show();

    if ($("#fruitTable tr:visible").length < 1) {
        $("#NoFilteredFruits").show();
        $("#fruitTable").hide();
    }
}

问题

在开发人员工具中检查时,JS执行此语句

if ($("#fruitTable tr:visible").length < 1)

在此之前,

 else {
            $('#fruitTable tr[data-status="' + elm.id + '"]').hide("up");
        }

我的意思是它执行它,但它没有改变,例如在判断if语句之前,它不会隐藏任何行。

请注意,我在不同的地方使用CheckFruitExists,所以我想将其分开。

1 个答案:

答案 0 :(得分:1)

JavaScript和DOM的操作是单线程的。浏览器通过将项目放入队列并一个接一个地执行它们来工作。当您更新DOM时,实际发生的是它将请求更新到队列末尾,因此它将在您的JavaScript运行完成后发生。在这种情况下,您需要做的是强制您的第二个函数转到此队列的末尾,因此它可以在DOM操作发生后运行。您可以通过在零超时中包含对函数的调用来执行此操作:

window.setTimeout(CheckFruitExists, 0);

这将导致它被添加到执行队列的末尾,现在应该在DOM更新发生后运行。

<强>更新

根据我的评论,jQuery visible selector会考虑动画周期中的元素:

  

在隐藏元素的动画期间,该元素在动画结束前被视为可见。在显示元素的动画期间,该元素在动画开始时被视为可见。

这意味着当您的CheckFruitExists函数运行时,该元素仍将是动画并且将被视为可见,无论它是隐藏还是显示。尝试删除动画以查看是否可以解决问题(您可能仍需要使用上面的setTimeout修复)。如果确实如此,并且您仍希望使用动画,则需要在CheckFruitExistshide的动画完整回调函数中调用show