如何在不让可怕的“停止运行此脚本?”对话框的情况下清除内容?

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


我有一个div,它有一个div。 像这样:

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

 

Heading1

...content here....

内容的总大小可能是200k。 每个div只包含一个HTML片段。 在其中,有许多元素,包含其他html元素,并且它们可以嵌套到5-8级深度。 没有什么特别的,我不认为。 ( 更新 :使用这个答案 ,我了解到片段中有139423个元素。)

在我添加完所有内容后,我创建了一个手风琴。 像这样:

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

一切正常。

问题是,当我尝试清除或删除报告div时,需要花费很多时间,我会得到3或4个弹出窗口,询问“你想停止运行这个脚本吗?”

我尝试了几种方法:

选项1:

  $('#report').accordion('destroy'); $('#report').remove(); $("#reportHolder").html("
");

选项2:

  $('#report').accordion('destroy'); $('#report').html(''); $("#reportHolder").html("
");

选项3:

  $('#report').accordion('destroy'); $("#reportHolder").html("
");

在评论中得到建议后,我也尝试过:

选项4:

  $('#report').accordion('destroy'); $('#report').empty(); $("#reportHolder").html("
");

它无论如何都会挂起很长一段时间。

手风琴(’destroy’)的召唤似乎不是延迟的根源。 这是报告div中html内容的擦除。

这是jQuery 1.3.2。

编辑 – 固定代码拼写错误。

ps:这发生在FF3.5以及IE8上。


问题:

  1. 花了这么长时间?

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


附录

在“选项4”期间,我在FF中进入了调试器,我看到的堆栈跟踪是:

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

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

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

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


有关:
jquery:最快的DOM插入?

您应该尝试绕过jQuery并在销毁手风琴后自己清空内容:

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

这会快得多,但可能会导致IE泄漏内存(jQuery竭力避免尝试确保没有引用阻止IE进行垃圾收集,这是移除数据的原因之一)。

我很确定这里会显示“为什么”(源自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); }); 

假设#report有10个直接子#report这会将删除操作拆分为10个单独的事件循环,这可能会解决您的长处理延迟问题。