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


当前回答

为什么我们不在这里使用最简单的方法“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方法没有问题。

元素。innerHTML = ""(或.textContent)是目前为止最快的解决方案

这里的大多数答案都是基于有缺陷的测试

例如: https://jsperf.com/innerhtml-vs-removechild/15 该测试不会在每次迭代之间向元素添加新的子元素。第一次迭代将删除元素的内容,然后每一次迭代都不执行任何操作。 在这种情况下,while (box. lastchild) box. removecchild (box. lastchild)更快,因为box. lastchild。lastChild在99%的情况下为null

这里有一个合适的测试:https://jsperf.com/innerhtml-conspiracy

最后,不要使用node. parentnode . replacechild (node. clonenode (false), node)。这将用节点本身的副本替换它的子节点。但是,这不会保留事件侦听器,并破坏对该节点的任何其他引用。

这是另一种方法:

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();
}
 let el = document.querySelector('#el');
 if (el.hasChildNodes()) {
      el.childNodes.forEach(child => el.removeChild(child));
 }

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的元素