Javascript SetTimeout在函数执行一次后停止
实际上,这是在试图回答另一个问题时产生的问题: 我提供了伪代码和Derek朕會功夫 提供代码。然而,当我想给代码添加一个短暂的延迟,以便我们能够看到发生了什么时,它会停止正常执行。SetTimeOut在执行一次后停止 小提琴: JQuery代码:Javascript SetTimeout在函数执行一次后停止,javascript,jquery,Javascript,Jquery,实际上,这是在试图回答另一个问题时产生的问题: 我提供了伪代码和Derek朕會功夫 提供代码。然而,当我想给代码添加一个短暂的延迟,以便我们能够看到发生了什么时,它会停止正常执行。SetTimeOut在执行一次后停止 小提琴: JQuery代码: function RemoveNode(node) { for (var i = node.children.length - 1; i >= 0; i--) { setTimeout(RemoveNode(node.chi
function RemoveNode(node) {
for (var i = node.children.length - 1; i >= 0; i--) {
setTimeout(RemoveNode(node.children[i]));
}
$(node).remove();
}
RemoveNode($(".parent")[0]);
我尝试使用window.setTimeout()
和function(){}
内部调用来删除节点,但没有成功。同时,此代码正确执行:
function RemoveNode(node){
for(var i = node.children.length - 1; i >= 0; i--){
RemoveNode(node.children[i]);
alert("hi");
}
$(node).remove();
}
RemoveNode($(".parent")[0]);
编辑:
为了澄清,在下面的示例中,我想在每次调用RemoveNode之前添加2个wait
function RemoveNode(node) {
for (var i = node.children.length - 1; i >= 0; i--) {
//Something like sleep(2000);
RemoveNode(node.children[i]);
}
$(node).remove();
}
RemoveNode($(".parent")[0]);
如果您试图缓慢地删除DOM子项,那么下面是一个简单的示例,说明如何使用计时器执行此操作:
function removeSlowly() {
function removeNext() {
var item = $("#top li:last").remove();
if (item.length) {
setTimeout(removeNext, 1000);
}
}
removeNext();
}
关于对您当前代码的评论: 您必须将函数引用传递给
setTimeout()
,并且必须将时间值作为第二个参数传递,并且必须具有正确数量的匹配参数
因此,更改代码如下:
setTimeout(RemoveNode(node.children[i]);
致:
当您尝试只传递RemoveNode(node.children[i])
时,您将立即执行该函数(这是parens所做的),然后将执行该函数的返回结果传递给setTimeout()
。由于返回值不是函数,`setTimeout()不需要执行任何操作,因此您的函数只能被调用一次
仅供参考,您还存在各种语法错误(缺少参数和参数),因此您需要在代码的其余部分清除这些错误
此外,即使在修复了此处的
setTimeout()
代码后,此处仍存在一些逻辑问题:
function RemoveNode(node) {
for (var i = node.children.length - 1; i >= 0; i--) {
setTimeout(function() {
RemoveNode(node.children[i]);
}, 1000);
}
$(node).remove();
}
首先,i
的值在setTimeout()
回调函数中不正确,因为
for
循环将已完成执行,因此i
将在循环结束时具有值。这可以用闭包来修复
然后,在已删除父项之后,尝试对子项调用RemoveNode()
。这有什么意义?子对象已从DOM中删除
您可以像这样解决i
的问题,但我不确定在子对象上调用RemoveNode有什么意义,因为它们已经从DOM中删除了
function RemoveNode(node) {
for (var i = node.children.length - 1; i >= 0; i--) {
(function(index) {
setTimeout(function() {
RemoveNode(node.children[index]);
}, 1000);
})(i);
}
$(node).remove();
}
如果您试图缓慢地删除DOM子项,那么下面是一个简单的示例,说明如何使用计时器执行此操作:
function removeSlowly() {
function removeNext() {
var item = $("#top li:last").remove();
if (item.length) {
setTimeout(removeNext, 1000);
}
}
removeNext();
}
关于对您当前代码的评论: 您必须将函数引用传递给
setTimeout()
,并且必须将时间值作为第二个参数传递,并且必须具有正确数量的匹配参数
因此,更改代码如下:
setTimeout(RemoveNode(node.children[i]);
致:
当您尝试只传递RemoveNode(node.children[i])
时,您将立即执行该函数(这是parens所做的),然后将执行该函数的返回结果传递给setTimeout()
。由于返回值不是函数,`setTimeout()不需要执行任何操作,因此您的函数只能被调用一次
仅供参考,您还存在各种语法错误(缺少参数和参数),因此您需要在代码的其余部分清除这些错误
此外,即使在修复了此处的
setTimeout()
代码后,此处仍存在一些逻辑问题:
function RemoveNode(node) {
for (var i = node.children.length - 1; i >= 0; i--) {
setTimeout(function() {
RemoveNode(node.children[i]);
}, 1000);
}
$(node).remove();
}
首先,i
的值在setTimeout()
回调函数中不正确,因为
for
循环将已完成执行,因此i
将在循环结束时具有值。这可以用闭包来修复
然后,在已删除父项之后,尝试对子项调用RemoveNode()
。这有什么意义?子对象已从DOM中删除
您可以像这样解决i
的问题,但我不确定在子对象上调用RemoveNode有什么意义,因为它们已经从DOM中删除了
function RemoveNode(node) {
for (var i = node.children.length - 1; i >= 0; i--) {
(function(index) {
setTimeout(function() {
RemoveNode(node.children[index]);
}, 1000);
})(i);
}
$(node).remove();
}
为了补充jfriend00已经说过的话(这些话都是正确的),您可能想看看这个: 我不确定您希望删除操作返回dom的确切距离,以及您对删除操作方式的确切意图,但这将每两秒钟删除叶节点和一个父节点。它展示了如何使用setTimeout和递归
var interval = 2000;
function RemoveNode($node) {
if( $node.children().length > 0 )
{
$node.children().each(function(){
RemoveNode($(this));
});
}
else
{
setTimeout(
function()
{
var $parent = $node.parent();
$node.remove();
if( $parent.children().length == 0 )
{
$parent.remove();
}
},
interval
);
interval += 2000;
}
}
RemoveNode($(".parent"));
更新
请参见:
如果元素具有可移动的
类,这将逐个删除元素。removable
类是这样的,我们不会逐个删除树上的每个元素,例如li
和ul
。如果希望两个父级并行删除,则从代码中取出.first()
var interval = 2000;
function RemoveNode($node) {
var $removable = $node.find('.removable').first();
if( $removable.length > 0 )
{
RemoveNode($removable);
}
else if( $node.hasClass('topParent') == false )
{
//this is a leaf removable node.
setTimeout(
function()
{
var $parent = $node.parent().closest('.removable');
$node.remove();
RemoveNode($parent);
},
interval
);
}
}
RemoveNode($(".topParent"));
HTML:
- 哎
- 嘿1
- 嘿2
- 哎
- 嘿1
- 嘿2
为了补充jfriend00已经说过的话(这些话都是正确的),您可能想看看这个:
我不确定您希望删除操作返回dom的确切距离,以及您对删除操作方式的确切意图,但这将每两秒钟删除叶节点和一个父节点。它展示了如何使用setTimeout和递归。