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


当前回答

迭代地从DOM中删除节点的所有子节点的一行程序

Array.from(node.children).forEach(c => c.remove())

Or

[...node.children].forEach(c => c.remove())

其他回答

目前公认的答案是错误的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”,只有第一次迭代需要删除节点,所以结果是没有意义的,在发布的时候,这个线程中的测试设置不正确。

var empty_element = function (element) {

    var node = element;

    while (element.hasChildNodes()) {              // selected elem has children

        if (node.hasChildNodes()) {                // current node has children
            node = node.lastChild;                 // set current node to child
        }
        else {                                     // last child found
            console.log(node.nodeName);
            node = node.parentNode;                // set node to parent
            node.removeChild(node.lastChild);      // remove last node
        }
    }
}

这将删除元素中的所有节点。

为什么我们不在这里使用最简单的方法“remove”循环在while中。

const foo = document.querySelector(".foo");
while (foo.firstChild) {
  foo.firstChild.remove();     
}

选择父div 在While循环中使用“remove”方法消除第一个子元素,直到没有剩余。

如果你想把一些东西放回那个div, innerHTML可能更好。

我的例子:

<ul><div id="result"></div></ul>

<script>
  function displayHTML(result){
    var movieLink = document.createElement("li");
    var t = document.createTextNode(result.Title);
    movieLink.appendChild(t);
    outputDiv.appendChild(movieLink);
  }
</script>

如果我使用. firstchild或. lastchild方法,displayHTML()函数之后不会工作,但使用. innerhtml方法没有问题。

jQuery的其他方法

var foo = $("#foo");
foo.children().remove();
//or
$("*", foo ).remove();
//or
foo.html("");
//or
foo.empty();