代码之家  ›  专栏  ›  技术社区  ›  Cheeso

如何才能清除内容而不出现可怕的“停止运行此脚本?”对话框?

  •  3
  • Cheeso  · 技术社区  · 14 年前


    我有一个div,上面有一个div。像这样:

    <div id='reportHolder' class='column'>
      <div id='report'> </div>
    </div>
    

    在内部div中,我添加了一堆(7-12)成对的a和div元素,如下所示:

    <h4><a>Heading1</a></h4>
    <div> ...content here....</div>
    

    内容的总大小,可能是20万。每个div只包含一段HTML。在它里面,有许多 <span> 元素,包含其他html元素,它们嵌套到5-8层。我觉得没什么特别的( 更新 :使用 this answer ,我知道碎片里有139423个元素。)

    在我添加所有内容之后,

    $('#report').accordion({collapsible:true, active:false});
    

    一切正常。

    问题是,当我试图清除或删除report div时,需要花费很长时间,并且会出现3到4个弹出窗口,询问“是否要停止运行此脚本?”

    我试过几种方法:

    方案1:

        $('#report').accordion('destroy');
        $('#report').remove();
        $("#reportHolder").html("<div id='report'> </div>");
    

    方案2:

        $('#report').accordion('destroy');
        $('#report').html('');
        $("#reportHolder").html("<div id='report'> </div>");
    

    方案3:

        $('#report').accordion('destroy');
        $("#reportHolder").html("<div id='report'> </div>");
    

        $('#report').accordion('destroy');
        $('#report').empty();
        $("#reportHolder").html("<div id='report'> </div>");
    

    不管怎样,它会挂很长一段时间。

    对手风琴的召唤(“毁灭”)似乎不是延迟的原因。它是删除report div中的html内容。

    这是jquery1.3.2。

    编辑 -修正了代码错误。


    问题:

    1. 如何更快地删除内容?


    附录

    在“选项4”期间,我闯入了FF中的调试器,我看到的stacktrace是:

    data()
    trigger()
    triggerHandler()
    add()
    each()
    each()
    add()
    empty()
    each()
    each()
    (?)()    // <<-- this is the call to empty()
    ResetUi()  // <<-- my code
    onclick
    

    我不明白为什么add()在堆栈中。我正在删除内容,而不是添加内容。恐怕在remove(all)上下文中,jQuery做了一些幼稚的事情。就像它抓取html内容一样,文本是否替换以删除一个html元素,然后调用.add()来放回剩下的内容。

    有没有办法告诉jQuery在从dom中删除HTML内容时不要传播事件?

    在Windows窗体中,某些控件上有BeginUpdate/EndUpdate对。我想要这样的东西,但是对于jQuery。


    相关:
    jquery: fastest DOM insertion ?

    2 回复  |  直到 7 年前
        1
  •  3
  •   C Snover    14 年前

    您应该尝试绕过jQuery,在销毁accordion之后自己清空内容:

    $('#report')[0].innerHTML = '';
    

        2
  •  1
  •   gnarf    14 年前

    我很确定“为什么”会在这里揭晓(来源于 jQuery 1.4.2 ):

    empty: function() {
      for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
        // Remove element nodes and prevent memory leaks
        if ( elem.nodeType === 1 ) {
          jQuery.cleanData( elem.getElementsByTagName("*") );
        }
    
        // Remove any remaining nodes
        while ( elem.firstChild ) {
          elem.removeChild( elem.firstChild );
        }
      }
    
      return this;
    },
    
    cleanData: function( elems ) {
      var data, id, cache = jQuery.cache,
          special = jQuery.event.special,
          deleteExpando = jQuery.support.deleteExpando;
    
      for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
        if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
          continue;
        }
    
        id = elem[ jQuery.expando ];
    
        if ( id ) {
          data = cache[ id ];
    
          if ( data && data.events ) {
            for ( var type in data.events ) {
              if ( special[ type ] ) {
                jQuery.event.remove( elem, type );
              } else {
                removeEvent( elem, type, data.handle );
              }
            }
          }
    
          if ( deleteExpando ) {
            delete elem[ jQuery.expando ];
          } else if ( elem.removeAttribute ) {
            elem.removeAttribute( jQuery.expando );
          }
    
          delete cache[ id ];
        }
      }
    }
    

    请注意 empty() 函数(以及删除DOM元素的任何其他函数)将调用 cleanData() expando 属性并解除绑定的事件的绑定,删除内部缓存中的所有数据,以及其他内容。

    $('#report').children().each(function() {
      var $this = $(this); 
      setTimeout(function() { $this.remove(); }, 0);
    });
    

    假设有10个 #report 这将把删除操作分成10个独立的事件循环,这可能会解决长时间的处理延迟问题。