我有一个画廊,里面有一长串缩略图。为了防止 DOM 被节点填满,我正在重用它们。从 DOM 中删除节点的最佳方法是什么(不使用库)?
使用innerHTML = ""
将解析并创建一个新的空文本节点,但循环和删除子节点会导致回流?
我有一个画廊,里面有一长串缩略图。为了防止 DOM 被节点填满,我正在重用它们。从 DOM 中删除节点的最佳方法是什么(不使用库)?
使用innerHTML = ""
将解析并创建一个新的空文本节点,但循环和删除子节点会导致回流?
你至少有四个选择:
innerHTML = ""
如您在问题中所示使用。它将确保您调用它的元素根本没有子节点,并且不会创建任何新节点。它是指定且可靠的跨浏览器(尽管有一个 IE 错误可能会或可能不会影响您的代码),并且可能相当有效。
使用textContent = ""
,它也是指定且可靠的跨浏览器(IE9+),有趣的是,IE11(至少)似乎没有textContent
与innerHTML
. 它还具有不需要 HTML 解析器的优点,当然您提供的字符串应该innerHTML
是 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 = ""
会是最快的,至少在有很多孩子的情况下。但是性能通常无关紧要,这是一种极其罕见的情况,这将是您代码中明显缓慢的部分。如果遇到重要情况,请使用目标浏览器中的每个选项测试您的实际代码,然后选择最有效的选项。
人们喜欢综合基准,但综合基准非常不可靠并且对基准假设(例如被移除的儿童数量)敏感。
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.replaceChildren()
,它将清空节点。它快速、干净,并且使您的意图清晰。