在Firefox中,我使用以下代码将文本插入~500 DIV:
$(".divs").text("default"); // ~500 DIVs
在我的计算机上,如果DIV为空,则一直需要 9ms 。但是,如果DIV已经包含文本,则相同的代码始终需要 18ms 。
为什么空DIV在插入文本时要快2倍(jQuery是否需要先清空DIV)?并且,有没有办法提高替换已包含文本的DIV中的文本的性能?
注意:在IE 7中,速度差异并不那么显着。在空DIV中插入文本的速度提高了约1.5倍。
答案 0 :(得分:6)
如果要插入的文字 NOT 需要转义,那么您可能需要尝试以下操作:
$(".div").each(function(){
this.innerHTML = "default";
});
当您使用method .text()
时,jQuery会对文本进行一些处理。
我们需要注意这个方法 转义提供的字符串 必要的,以便它将呈现 在HTML中正确。为此,它打电话 DOM方法
.createTextNode()
, 用...替换特殊字符 他们的HTML实体等价物(例如 < for<)。
修改强>
为了避免.each()
方法的惩罚,您可以尝试以下方法:
var divs = $(".divs"),
i = 0,
len = divs.length;
while(len--) {
divs[len].innerHTML = "default";
}
如果这不能让您获得任何性能提升,那么它绝对是一个浏览器实现问题。至少这将排除jQuery性能问题/错误。
答案 1 :(得分:6)
如果您想要所有浏览器的最快解决方案,请使用textContent
(如果支持)并回退到innerText
/ innerHTML
,否则 [Test] (知道 gotchas )。
/**
* Replaces text for all elements in the given array.
* @param {Array} elems
* @param {String} text
*/
var replaceText = (function(){
var dummy = document.createElement("div");
dummy.innerHTML = "text";
var TEXT = (dummy.textContent === 'text') ? 'textContent' : 'innerText';
return function(elems, text) {
for (var i = elems.length; i--;) {
elems[i][TEXT] = text;
}
};
})();
比jQuery文本更快:
答案 2 :(得分:3)
是的,当元素具有子元素时,此方法的原因是因为jQuery的.text()
方法首先运行.empty()
方法然后.append(document.createTextNode(text))
来自jQuery.text
// ...
return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
// ...
我指出这一点的原因是.empty()
方法调用.cleanData()
方法删除与其子节点关联的任何数据和/或事件,然后执行标准{{1}在其所有子节点上删除它们的方法,这是已经包含文本的div更新速度较慢的主要原因。
你的问题的解决方案是编写自己的,vanilla,javaScript函数来更新div的文本,但要确保你没有通过jQuery将任何点击事件或数据附加到它们,因为你肯定会有一些内存泄漏。
答案 3 :(得分:3)
您可以通过重复使用现有文本节点来获得性能。
仅包含文本的DIV元素是一个DOM元素,它包含一个类型为文本节点的子节点。文本内容存储在此文本节点中,而不是存储在其父DIV元素中。
JQuery中的.text(),HTML DOM中的.innerHTML(),甚至.innerText()和.textContent()等方法的主要问题是它们都创建了 new 文本节点(即使已经存在)。更具体地说,上面列出的所有方法都是从删除所有 DOM子节点开始的,包括最终预先存在的文本节点(这也是由innerHTML,innerText和textContent的实现完成的)。这使得上下文元素(在您的情况下为DIV)为空,完全没有任何子项。然后,他们创建一个类型为text node的 new 子节点,为其分配新文本,并将其附加到context元素。 innerHTML还尝试解析输入HTML字符串并从中构造一个DOM片段。
我知道替换现有文本节点的最快方法如下:
var divs = $(".divs").get(),
len = divs.length;
while(--len) {
divs[len].firstChild.data = "default";
}
此方法不会创建新的子节点,而只是替换现有文本节点的文本。显然,此方法假定文本节点已存在。 为此,初始文档可以使用DIV内的任何非空文本进行初始化(并排除任何其他子元素)。
答案 4 :(得分:1)
如果您不需要转义html标记(即用<a>
替换<a>
),那么.html可能会更快。同样是的,它需要在用新内容替换它之前清空div。