如何在JavaScript中删除DOM节点的所有子元素?
假设我有以下(丑陋的)HTML:
<p id="foo">
<span>hello</span>
<div>world</div>
</p>
然后我像这样获取我想要的节点
var myNode = document.getElementById("foo");
我怎么能删除foo的孩子,这样就<p id="foo"></p>是剩下的?
我能不能这样做:
myNode.childNodes = new Array();
或者我应该使用一些组合的removeElement?
我希望答案是直接的DOM;不过,如果你在jQuery中提供了一个dom专用的答案,会有额外的加分。
ES6+浏览器(2016年之后发布的主要浏览器)的最佳删除方法:
也许有很多方法可以做到这一点,例如Element.replaceChildren()。
我想向您展示一个有效的解决方案,只有一个重绘和回流,支持所有ES6+浏览器。
function removeChildren(cssSelector, parentNode){
var elements = parentNode.querySelectorAll(cssSelector);
let fragment = document.createDocumentFragment();
fragment.textContent=' ';
fragment.firstChild.replaceWith(...elements);
}
用法:removeChildren('.foo',document.body);:删除<body>中所有className为foo的元素
作为对DanMan, Maarten和Matt的回应。克隆一个节点,以设置文本确实是一个可行的方法,在我的结果。
// @param {node} node
// @return {node} empty node
function removeAllChildrenFromNode (node) {
var shell;
// do not copy the contents
shell = node.cloneNode(false);
if (node.parentNode) {
node.parentNode.replaceChild(shell, node);
}
return shell;
}
// use as such
var myNode = document.getElementById('foo');
myNode = removeAllChildrenFromNode( myNode );
这也适用于不在dom中的节点,当试图访问parentNode时返回null。此外,如果您需要在添加内容之前确保节点是空的,这是非常有用的。考虑下面的用例。
// @param {node} node
// @param {string|html} content
// @return {node} node with content only
function refreshContent (node, content) {
var shell;
// do not copy the contents
shell = node.cloneNode(false);
// use innerHTML or you preffered method
// depending on what you need
shell.innerHTML( content );
if (node.parentNode) {
node.parentNode.replaceChild(shell, node);
}
return shell;
}
// use as such
var myNode = document.getElementById('foo');
myNode = refreshContent( myNode );
我发现这个方法在替换元素中的字符串时非常有用,如果你不确定节点将包含什么,与其担心如何清理混乱,不如从头开始。