我有几个过滤器显示或隐藏表中的表行,然后检查是否没有行可见,然后向表中添加一条消息,说明没有行。
这就是我尝试这样做的方法,但是失败了,也许我不知道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
,所以我想将其分开。
答案 0 :(得分:1)
JavaScript和DOM的操作是单线程的。浏览器通过将项目放入队列并一个接一个地执行它们来工作。当您更新DOM时,实际发生的是它将请求更新到队列末尾,因此它将在您的JavaScript运行完成后发生。在这种情况下,您需要做的是强制您的第二个函数转到此队列的末尾,因此它可以在DOM操作发生后运行。您可以通过在零超时中包含对函数的调用来执行此操作:
window.setTimeout(CheckFruitExists, 0);
这将导致它被添加到执行队列的末尾,现在应该在DOM更新发生后运行。
<强>更新强>
根据我的评论,jQuery visible selector会考虑动画周期中的元素:
在隐藏元素的动画期间,该元素在动画结束前被视为可见。在显示元素的动画期间,该元素在动画开始时被视为可见。
这意味着当您的CheckFruitExists
函数运行时,该元素仍将是动画并且将被视为可见,无论它是隐藏还是显示。尝试删除动画以查看是否可以解决问题(您可能仍需要使用上面的setTimeout
修复)。如果确实如此,并且您仍希望使用动画,则需要在CheckFruitExists
和hide
的动画完整回调函数中调用show
。