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


当前回答

仅函数方法:

const domChildren = (el) => Array.from(el.childNodes)
const domRemove = (el) => el.parentNode.removeChild(el)
const domEmpty = (el) => domChildren(el).map(domRemove)

domChildren中的"childNodes"将给出一个直接子元素的nodeList,如果没有找到则为空。为了在nodeList上进行映射,domChildren将它转换为数组。domEmpty将函数domRemove映射到所有移除它的元素上。

使用示例:

domEmpty(document.body)

从body元素中移除所有子元素。

其他回答

选项1 A:清除innerHTML。

这种方法很简单,但可能不适合高性能应用程序,因为它调用浏览器的HTML解析器(尽管浏览器可能针对值为空字符串的情况进行优化)。

doFoo。Onclick = () => { const myNode = document.getElementById("foo"); myNode。innerHTML = "; } <div id='foo' style="height: 100px;宽度:100 px;边框:1px纯黑色;" > < span >你好> < /跨度 < / div > <button id='doFoo'>通过innerHTML删除</button>

选项1 B:清除文本内容

如上所述,但是使用. textcontent。根据MDN,这将比innerHTML更快,因为浏览器不会调用他们的HTML解析器,而是立即用单个#text节点替换元素的所有子元素。

doFoo。Onclick = () => { const myNode = document.getElementById("foo"); myNode。textContent = "; } <div id='foo' style="height: 100px;宽度:100 px;边框:1px纯黑色;" > < span >你好> < /跨度 < / div > <按钮id='doFoo'>删除通过textContent</按钮>

选项2 A:循环删除每个lastChild:

这个答案的早期编辑使用了firstChild,但在计算机科学中更新为使用lastChild,一般来说,删除集合的最后一个元素比删除第一个元素要快得多(这取决于集合是如何实现的)。 循环继续检查firstChild,以防检查firstChild比检查lastChild快(例如,如果元素列表被UA实现为有向链表)。

doFoo。Onclick = () => { const myNode = document.getElementById("foo"); while (myNode.firstChild) { myNode.removeChild (myNode.lastChild); } } <div id='foo' style="height: 100px;宽度:100 px;边框:1px纯黑色;" > < span >你好> < /跨度 < / div > <button id='doFoo'>通过lastChild-loop删除</button>

选项2 B:循环删除每个lastElementChild:

这种方法保留了所有非element(即#text节点和<!)——comments——>)父类的子类(但不是它们的后代)——这可能在你的应用程序中是可取的(例如,一些模板系统使用内联HTML注释来存储模板指令)。 这种方法直到最近几年才被使用,因为Internet Explorer只在IE9中添加了对lastElementChild的支持。

doFoo。Onclick = () => { const myNode = document.getElementById("foo"); while (myNode.lastElementChild) { myNode.removeChild (myNode.lastElementChild); } } <div id='foo' style="height: 100px;宽度:100 px;边框:1px纯黑色;" > <!——这条评论不会被删除——> < span > <你好!-></span> . -></span> . - <!——但这只不会。--> < / div > <button id='doFoo'>通过lastElementChild-loop删除</button>

好处:元素。clearChildren monkey-patch:

我们可以在JavaScript中的Element原型中添加一个新的method-property,以简化对它的调用,只调用el. clearchildren()(其中el是任何HTML元素对象)。 (严格地说,这是一个猴子补丁,而不是一个polyfill,因为这不是一个标准的DOM特性或缺失的特性。请注意,在许多情况下,不鼓励打猴子补丁。)

if( typeof Element.prototype.clearChildren === 'undefined' ) { Object.defineProperty(Element.prototype, 'clearChildren', { configurable: true, enumerable: false, value: function() { while(this.firstChild) this.removeChild(this.lastChild); } }); } <div id='foo' style="height: 100px; width: 100px; border: 1px solid black;"> <span>Hello <!-- This comment WILL be removed --></span> </div> <button onclick="this.previousElementSibling.clearChildren()">Remove via monkey-patch</button>

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
        }
    }
}

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

这是一个纯粹的javascript,我不使用jQuery,但工作在所有浏览器甚至IE,这是非常简单的理解

   <div id="my_div">
    <p>Paragraph one</p>
    <p>Paragraph two</p>
    <p>Paragraph three</p>
   </div>
   <button id ="my_button>Remove nodes ?</button>

   document.getElementById("my_button").addEventListener("click",function(){

  let parent_node =document.getElemetById("my_div"); //Div which contains paagraphs

  //Let find numbers of child inside the div then remove all
  for(var i =0; i < parent_node.childNodes.length; i++) {
     //To avoid a problem which may happen if there is no childNodes[i] 
     try{
       if(parent_node.childNodes[i]){
         parent_node.removeChild(parent_node.childNodes[i]);
       }
     }catch(e){
     }
  }

})

or you may simpli do this which is a quick way to do

document.getElementById("my_button").addEventListener("click",function(){

 let parent_node =document.getElemetById("my_div");
 parent_node.innerHTML ="";

})

用jQuery:

$("#foo").find("*").remove();

innerText是赢家!http://jsperf.com/innerhtml-vs-removechild/133。在所有之前的测试中,父节点的内部dom在第一次迭代时被删除,然后innerHTML或removecchild应用于空div。