如何在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专用的答案,会有额外的加分。


当前回答

var myNode = document.getElementById("foo");
var fc = myNode.firstChild;

while( fc ) {
    myNode.removeChild( fc );
    fc = myNode.firstChild;
}

如果您的后代有可能受到jQuery影响,那么您必须使用一些方法来清理jQuery数据。

$('#foo').empty();

jQuery .empty()方法将确保任何与被删除的元素相关联的jQuery数据将被清除。

如果您只是使用DOM方法删除子元素,那么这些数据将会保留。

其他回答

这是另一种方法:

function removeAllChildren(theParent){

    // Create the Range object
    var rangeObj = new Range();

    // Select all of theParent's children
    rangeObj.selectNodeContents(theParent);

    // Delete everything that is selected
    rangeObj.deleteContents();
}

目前公认的答案是错误的innerHTML更慢(至少在IE和Chrome),正如m93a正确提到的。

Chrome和FF使用这种方法会显着更快(这将破坏附加的jquery数据):

var cNode = node.cloneNode(false);
node.parentNode.replaceChild(cNode, node);

FF和Chrome远远排在第二,IE最快:

node.innerHTML = '';

InnerHTML不会破坏你的事件处理程序或打破jquery引用,它也建议作为一个解决方案在这里: https://developer.mozilla.org/en-US/docs/Web/API/Element.innerHTML。

最快的DOM操作方法(仍然比前两个慢)是范围移除,但是直到IE9才支持范围。

var range = document.createRange();
range.selectNodeContents(node);
range.deleteContents();

上面提到的其他方法看起来差不多,但比innerHTML慢很多,除了jquery(1.1.1和3.1.1),它比其他任何方法都要慢得多:

$(node).empty();

证据:

http://jsperf.com/innerhtml-vs-removechild/167 http://jsperf.com/innerhtml-vs-removechild/300 https://jsperf.com/remove-all-child-elements-of-a-dom-node-in-javascript (重新启动jsperf的新url,因为编辑旧url不工作)

Jsperf的“per-test-loop”通常被理解为“per-iteration”,只有第一次迭代需要删除节点,所以结果是没有意义的,在发布的时候,这个线程中的测试设置不正确。

使用现代Javascript,与删除!

const parent = document.getElementById("foo")
while (parent.firstChild) {
    parent.firstChild.remove()
}

这是在ES5中编写节点删除的一种较新的方法。它是香草的JS,读起来比依赖父母要好得多。

支持所有现代浏览器。

浏览器支持- 97% 21年6月

如果你使用jQuery:

$('#foo').empty();

如果你没有:

var foo = document.getElementById('foo');
while (foo.firstChild) foo.removeChild(foo.firstChild);

简单快速使用for循环!!

var myNode = document.getElementById("foo");

    for(var i = myNode.childNodes.length - 1; i >= 0; --i) {
      myNode.removeChild(myNode.childNodes[i]);
    }

这将在<span>标签不起作用!