回调中的jQuery .remove()调用触发无限循环 [英] jQuery .remove() call in callback triggers infinite loop

查看:120
本文介绍了回调中的jQuery .remove()调用触发无限循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

虽然问题本身似乎已经解决,但我希望有人能对此问题的解释...

While I have the problem itself seemingly resolved, I'm hoping someone can shed some light on the why of this...

下面是同一功能的两个快照,其作用是删除包含用户反馈消息的div.设置为使用可选的超时,如果指定了超时,它将使用setTimeout()对其自身进行调用,然后删除div.

Below are two snapshots of the same function whose job is to remove a div that contains a user feedback message. It's setup to use an optional timeout, if a timeout is specified it makes a call to itself using setTimeout() which then removes the div.

函数的两个版本之间唯一的区别是调用 this.remove()的位置-在有问题的版本中,我使用

The only difference between the two versions of the function is where this.remove() is called - in the problem version I send a message to the log using blackbirdjs first and then call this.remove() - after this executes the log is flooded with unending log messages of "Removing feedback div..." as fast as the browser can pump them in.

但是,在工作版本中,我只是颠倒了顺序,一切正常执行,一切都很好...

In the working version, however, I simply reverse the order and everything executes normally and all is well...

我很困惑,我认为这种情况下的顺序是微不足道的,但显然不是.谁能阐明为什么会这样?这是jQuery的错误还是黑鸟的问题,或者是某种怪异的JavaScript怪癖?

I'm boggled, I would think that the order in this case would be trivial but apparently not. Can anyone shed some light on why this would be happening? Is this a jQuery bug or a problem with blackbird or some kind of weird quirk of JavaScript in general?

注意:
我使用调用Confirm()取得了一些成功的结果-如果返回false,我告诉它返回并停止了它-但是,在remove调用之后添加return无效.

NOTE:
I had some mixed success using a call to confirm() - if it came back false I told it to return and this stopped it - however, just adding return after the remove call had no effect.

有趣的是,这两个版本在IE8中似乎都可以正常工作-那么这可能是firefox/gecko问题吗?

Interestingly enough, either version seems to work fine in IE8 - so this may be a firefox/gecko problem?

问题代码:

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);
    }
}

推荐答案

您应该已经检查了浏览器错误控制台,而不是仅仅依赖blackbirdjs控制台.

You should have checked your browsers error console instead of just relying on the blackbirdjs console.

然后您会注意到,浏览器错误控制台也充满了错误消息(使用您的两个代码版本)

Then you would have noticed that the browsers error console is flooded with error messages too (with either of your code versions)

您的代码中的实际问题是

The actual problem in your code is

this.remove();

this是回调函数中的HTML DOM元素,并且不具有功能remove(),因此子级仅被隐藏而未被真正删除.在this.remove()上,您将获得一个例外.当回调函数引发异常时,jQuery最终陷入尝试执行其工作的无尽循环

this is a HTML DOM element in the callback-function and doesn't have the function remove() thus the children only get hidden but not really deleted. And on this.remove() you get an exception. As the callback-function throws an exception jQuery ends up in an endless loop trying to do its job

您需要做的是将元素包装在jQuery对象中.

What you need to do is wrapping the element in a jQuery object.

$(this).remove();


现在也很清楚为什么第二个版本似乎已修复该错误


Now it's also clear why the second version seems to have fixed the error

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甚至最终陷入无休止的循环中,如果这是正确的行为,则值得商bat,需要在jQuery的内部工作中进行更深入的研究.但这对你不感兴趣


The fact that jQuery even ends up in and endless loop and if this is correct behavior is debatable and needs more investigation deeper in the inner-workings of jQuery. But this isn't of interest to you

对于那些感兴趣的人,有真实的bug票证

For those interested there is realted bug ticket

http://dev.jquery.com/ticket/2846

这篇关于回调中的jQuery .remove()调用触发无限循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆