代码之家  ›  专栏  ›  技术社区  ›  Crazy Joe Malloy

回调中的jQuery.remove()调用触发无限循环

  •  1
  • Crazy Joe Malloy  · 技术社区  · 15 年前

    虽然我的问题似乎已经解决了,但我希望有人能对这个问题有所帮助 为什么? 关于这个。。。

    下面是同一函数的两个快照,其任务是删除包含用户反馈消息的div。设置为使用可选超时,如果指定了超时,则使用setTimeout()调用自身,然后删除div。

    函数的两个版本之间的唯一区别是 调用-在问题版本中,我使用 blackbirdjs 首先,然后调用this.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);
        }
    }
    
    2 回复  |  直到 15 年前
        1
  •  1
  •   jitter    15 年前

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

    然后,您会注意到浏览器错误控制台中也充斥着错误消息(使用您的任一代码版本)

    代码中的实际问题是

    this.remove();
    

    this remove() 因此,孩子们只会被隐藏,而不会被真正删除。等等 this.remove() 你会得到一个例外。当回调函数抛出一个异常时,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的内部工作进行更深入的研究。但你对此不感兴趣

    对于那些感兴趣的人,有一张不动产的虫子票

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

        2
  •  0
  •   jdigital    15 年前

    我看到过这样一个问题,但背景不同;然而,我怀疑根本原因是相同的。

    为什么IE8中不会出现这种情况,这可能是两个原因之一:不同浏览器的DOM结构不完全相同,或者当javascript代码遍历树时,IE8使用不同的策略来处理DOM节点插入。

    您可以尝试使用Firebug,在有问题的行周围放置一个断点,然后查看DOM树,看看是否可以发现这样的行为。