我有一个带有大量缩略图的图库。为了防止DOM被节点填满,我正在重复使用它们。在不使用库的情况下,最好的方法是从DOM中删除节点是什么?
使用 innerHTML = ""
将解析并创建一个新的空文本节点,但循环和删除子节点会导致重新渲染。
我有一个带有大量缩略图的图库。为了防止DOM被节点填满,我正在重复使用它们。在不使用库的情况下,最好的方法是从DOM中删除节点是什么?
使用 innerHTML = ""
将解析并创建一个新的空文本节点,但循环和删除子节点会导致重新渲染。
您至少有四种选择:
使用如问题中展示的 innerHTML = ""
。它会确保调用它的元素没有任何子节点,并且不会创建任何新节点。它是指定和跨浏览器可靠的(尽管存在可能影响您的代码的IE bug),并且可能相当高效。
使用 textContent = ""
,它也是指定和跨浏览器可靠的(IE9+),有趣的是,至少在IE11上看起来没有与 innerHTML
相关的bug,但是却具有优点,即不需要HTML解析器,而当然你给出的字符串应该是HTML。 (浏览器可能已经针对字符串为空时进行了优化。)
您可以在循环中使用 removeChild
,但这涉及到对DOM进行潜在的重复函数调用:
// assuming elm is the element
while (elm.firstChild) {
elm.removeChild(elm.firstChild);
}
您可以使用克隆元素替换父元素,不包括子元素:
// assuming elm is the element
const clone = elm.cloneNode(false);
parent.parentElement.replaceChild(clone, elm);
elm = clone;
请注意,与其他方法不同的是,这种方法将删除父元素上的任何事件处理程序。
如果我必须猜测,我会猜测textContent = ""
是最快的,至少在有 很多子元素的情况下是这样。但是性能通常并不重要,只有在极少数情况下,这才会成为您代码明显缓慢的部分。如果您遇到需要考虑性能的情况,请在目标浏览器中测试每个选项的实际代码,并选择最佳选项。
人们喜欢使用人工基准测试,但是人工基准测试非常不可靠,并且对基准假设(例如要删除的子元素数量)非常敏感。
如果您想清空一个元素,您也可以直接调用node.replaceChildren()
方法。这种方法非常快速、干净,并且能够清晰地表达您的意图。
function clearNode(node, clone = true) {
let emptyNode;
if (clone) {
emptyNode = node.cloneNode();
node.parentNode.replaceChild(emptyNode, node);
node = emptyNode;
}
else {
while (node.hasChildNodes()) {
node.removeChild(node.firstChild);
}
emptyNode = node;
}
return emptyNode;
}
node.innerHTML = ""
不会创建一个新的空节点,而是清空了node
。 - Alvin Wongimg
元素上设置href
属性即可。 - Bruno