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


当前回答

element.textContent = '';

它像innerText,除了标准。它比removecchild()稍微慢一点,但更容易使用,如果没有太多东西需要删除,则不会有太大的性能差异。

其他回答

刚刚看到有人在另一个问题中提到这个问题,我想我会添加一个我还没有看到的方法:

function clear(el) {
    el.parentNode.replaceChild(el.cloneNode(false), el);
}

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

clear函数获取元素并使用父节点将其自身替换为没有其子节点的副本。如果元素是稀疏的,则性能增益不大,但当元素有一堆节点时,性能增益就实现了。

我是这样做的

data = { "messages": [ [0, "userName", "message test"], [1, "userName1", "message test1"] ] } for (let i = 0; i < data.messages.length; i++) { var messageData = document.createElement('span') messageData.className = 'messageClass' messageData.innerHTML = `${data.messages[i][2]} ${'<br />'}` $(".messages").append(messageData) } $('#removeMessages').on('click', () => { node = $('.messages').get(0) while (node.firstChild) { node.firstChild.remove() } $('#removeMessages').toggle(500) $('#addMessages').toggle(500) }) $('#addMessages').on('click', () => { for (let i = 0; i < data.messages.length; i++) { var messageData = document.createElement('span') messageData.className = 'messageClass' messageData.innerHTML = `${data.messages[i][2]} ${'<br />'}` $(".messages").append(messageData) } $('#addMessages').toggle(500) $('#removeMessages').toggle(500) }) #addMessages{ display:none; } <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <div class="messages"></div> <button type='button' id="removeMessages">Remove</button> <button type='button' id="addMessages">Add MEssages</button>

作为对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 );

我发现这个方法在替换元素中的字符串时非常有用,如果你不确定节点将包含什么,与其担心如何清理混乱,不如从头开始。

 let el = document.querySelector('#el');
 if (el.hasChildNodes()) {
      el.childNodes.forEach(child => el.removeChild(child));
 }

简单的只有IE:

parentElement.removeNode(true);

True -意味着做深层移除-这意味着所有的子也被移除