回调中的jQuery.remove()调用触发无限循环
虽然我的问题似乎已经解决了,但我希望有人能解释一下为什么会这样 下面是同一函数的两个快照,其任务是删除包含用户反馈消息的div。设置为使用可选超时,如果指定了超时,则使用setTimeout()调用自身,然后删除div 函数的两个版本之间的唯一区别是调用了this.remove()——在问题版本中,我首先使用发送消息到日志,然后调用此.remove()——执行此操作后,日志中充斥着“Removing feedback div…”的无休止的日志消息浏览器可以以最快的速度将它们输入 然而,在工作版本中,我只是简单地颠倒顺序,一切正常执行,一切都很好 我很困惑,我会认为在这种情况下的顺序是微不足道的,但显然不是。有人能解释一下为什么会发生这种情况吗?这是jQuery的一个bug,还是blackbird的一个问题,还是JavaScript的某种奇怪的怪癖 注意:回调中的jQuery.remove()调用触发无限循环,jquery,firefox,infinite-loop,Jquery,Firefox,Infinite Loop,虽然我的问题似乎已经解决了,但我希望有人能解释一下为什么会这样 下面是同一函数的两个快照,其任务是删除包含用户反馈消息的div。设置为使用可选超时,如果指定了超时,则使用setTimeout()调用自身,然后删除div 函数的两个版本之间的唯一区别是调用了this.remove()——在问题版本中,我首先使用发送消息到日志,然后调用此.remove()——执行此操作后,日志中充斥着“Removing feedback div…”的无休止的日志消息浏览器可以以最快的速度将它们输入 然而,在工作版本
我通过调用confirm()获得了一些混合的成功-如果它返回false,我告诉它返回,这样就停止了它-但是,在remove调用之后添加return没有任何效果 有趣的是,这两个版本在IE8中似乎都可以正常工作——所以这可能是firefox/gecko的问题 问题代码:
function clear_feedback(target_container, timeout){
log.debug("timeout: " + timeout);
log.debug("target_container: " + target_container);
if(timeout == undefined){
log.info("removing target...");
$(target_container).children(".update_feedback").slideUp("slow",
function() {
log.info("Removing feedback div...");
this.remove();
}
);
}
else{
log.info("Setting timeout, THEN removing target...");
setTimeout("clear_feedback('" + target_container + "')", timeout);
}
}
function clear_feedback(target_container, timeout){
log.debug("timeout: " + timeout);
log.debug("target_container: " + target_container);
if(timeout == undefined){
log.info("removing target...");
$(target_container).children(".update_feedback").slideUp("slow",
function() {
this.remove();
log.info("Removing feedback div...");
}
);
}
else{
log.info("Setting timeout, THEN removing target...");
setTimeout("clear_feedback('" + target_container + "')", timeout);
}
}
工作代码:
function clear_feedback(target_container, timeout){
log.debug("timeout: " + timeout);
log.debug("target_container: " + target_container);
if(timeout == undefined){
log.info("removing target...");
$(target_container).children(".update_feedback").slideUp("slow",
function() {
log.info("Removing feedback div...");
this.remove();
}
);
}
else{
log.info("Setting timeout, THEN removing target...");
setTimeout("clear_feedback('" + target_container + "')", timeout);
}
}
function clear_feedback(target_container, timeout){
log.debug("timeout: " + timeout);
log.debug("target_container: " + target_container);
if(timeout == undefined){
log.info("removing target...");
$(target_container).children(".update_feedback").slideUp("slow",
function() {
this.remove();
log.info("Removing feedback div...");
}
);
}
else{
log.info("Setting timeout, THEN removing target...");
setTimeout("clear_feedback('" + target_container + "')", timeout);
}
}
我看到过这样一个问题,但背景不同;然而,我怀疑根本原因是相同的 如果查看log.info,您将看到它将一个节点插入到DOM中。如果其中一个jquery函数恰好在正确的位置(特别是在log.info插入节点的位置)遍历DOM,然后如果这导致调用回调,那么回调将插入另一个节点,最终进入无限循环 为什么IE8中不会出现这种情况,这可能是两个原因之一:不同浏览器的DOM结构不完全相同,或者当javascript代码遍历树时,IE8使用不同的策略来处理DOM节点插入
您可以尝试使用Firebug,在有问题的行周围放置一个断点,然后查看DOM树,看看是否可以发现这样的行为。我在不同的上下文中看到过类似的问题;然而,我怀疑根本原因是相同的 如果查看log.info,您将看到它将一个节点插入到DOM中。如果其中一个jquery函数恰好在正确的位置(特别是在log.info插入节点的位置)遍历DOM,然后如果这导致调用回调,那么回调将插入另一个节点,最终进入无限循环 为什么IE8中不会出现这种情况,这可能是两个原因之一:不同浏览器的DOM结构不完全相同,或者当javascript代码遍历树时,IE8使用不同的策略来处理DOM节点插入
您可以尝试使用Firebug,在有问题的行周围放置一个断点,然后查看DOM树,看看是否可以发现这样的行为。您应该检查浏览器的错误控制台,而不是仅仅依赖blackbirdjs控制台 然后,您会注意到浏览器错误控制台中也充斥着错误消息(使用您的任一代码版本) 代码中的实际问题是
this.remove();
此
是回调函数中的HTML DOM元素,没有函数remove()
,因此子项只会被隐藏,而不会被真正删除。在this.remove()
上,您会得到一个异常。当回调函数抛出一个异常时,jQuery就陷入了一个无休止的循环,试图完成它的工作
您需要做的是将元素包装到jQuery对象中
$(this).remove();
现在也很清楚为什么第二个版本似乎已经修复了错误
log.info("Removing feedback div..."); //error logged
this.remove(); //exception
this.remove(); //exception
//log line not executed as previous line threw exception
log.info("Removing feedback div...");
事实上,jQuery甚至会以无限循环结束,如果这是正确的行为,这是有争议的,需要对jQuery的内部工作进行更深入的研究。但你对此不感兴趣 对于那些感兴趣的人,有一张不动产的虫子票
您应该检查浏览器错误控制台,而不是仅仅依赖blackbirdjs控制台 然后,您会注意到浏览器错误控制台中也充斥着错误消息(使用您的任一代码版本) 代码中的实际问题是
this.remove();
此
是回调函数中的HTML DOM元素,没有函数remove()
,因此子项只会被隐藏,而不会被真正删除。在this.remove()
上,您会得到一个异常。当回调函数抛出一个异常时,jQuery就陷入了一个无休止的循环,试图完成它的工作
您需要做的是将元素包装到jQuery对象中
$(this).remove();
现在也很清楚为什么第二个版本似乎已经修复了错误
log.info("Removing feedback div..."); //error logged
this.remove(); //exception
this.remove(); //exception
//log line not executed as previous line threw exception
log.info("Removing feedback div...");
事实上,jQuery甚至会以无限循环结束,如果这是正确的行为,这是有争议的,需要对jQuery的内部工作进行更深入的研究。但你对此不感兴趣 对于那些感兴趣的人,有一张不动产的虫子票
酷-谢谢你提供的信息-我会调查并让你知道我发现了什么。酷-谢谢你提供的信息-我会调查并让你知道我发现了什么,如果发现了什么。嘎..../head slam on desk我还没有机会测试这个,可能下一段时间不会(我从周五开始休年假过圣诞节),但读了这篇文章后,错误似乎很明显……新手犯了错误。很抱歉,时间太长了