在JavaScript中删除DOM节点的所有子元素

我将如何去除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的答案。

选项1(慢得多,见下面的评论):

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

选项2(更快):

 var myNode = document.getElementById("foo"); while (myNode.firstChild) { myNode.removeChild(myNode.firstChild); } 

目前接受的答案是关于innerHTML慢(至less在IE和Chrome)错误,正如m93a正确提到的。

Chrome和FF使用这种方法会显着加快速度(这会破坏附加的jQuery数据):

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

在FF和Chrome中遥遥领先,在IE中速度最快:

 node.innerHTML = ''; 

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

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

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

提到的其他方法似乎是可比的,但比innerHTML慢得多,除了exception,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”通常被理解为“每次迭代”,只有第一次迭代才有删除的结果,所以结果是没有意义的,发布的时候这个线程的testing是不正确的。

 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方法删除子项,那么这些数据将保留。

如果你使用jQuery:

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

如果你不这样做:

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

最快的…

 var removeChilds = function (node) { var last; while (last = node.lastChild) node.removeChild(last); }; 

感谢安德烈Lushnikov他的链接到jsperf.com (酷网站!)。

如果你只想让没有子节点的节点也可以像这样做一个副本:

 var dupNode = document.getElementById("foo").cloneNode(false); 

取决于你想要达到的目标。

 element.textContent = ''; 

这就像innerText,除了标准。 这比removeChild() 慢了一点 ,但是如果你没有太多东西需要删除的话,使用起来会更容易一些,不会有很大的性能差异。

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

这是在ES5中编写节点删除的新方法。 这是香草JS和读取比以前的版本更好。

大多数用户应该有现代浏览器,或者如果需要的话可以下传。

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

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

这是另一种方法:

 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(); } 

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

通过Javascript删除节点的子节点的最简单的方法

 var myNode = document.getElementById("foo"); while(myNode.hasChildNodes()) { myNode.removeChild(myNode.lastChild); } 

有几个选项可以实现这一点:

最快的 ():

 while (node.lastChild) { node.removeChild(node.lastChild); } 

替代品(较慢):

 while (node.firstChild) { node.removeChild(node.firstChild); } while (node.hasChildNodes()) { node.removeChild(node.lastChild); } 

基准与build议的选项

我看到有人在做:

 while (el.firstNode) { el.removeChild(el.firstNode); } 

那么有人说使用el.lastNode更快

但是我会认为这是最快的:

 var children = el.childNodes; for (var i=children.length - 1; i>-1; i--) { el.removeNode(children[i]); } 

你怎么看?

ps:这个话题对我来说是一个救命的人。 我的Firefox插件被拒绝因为我使用了innerHTML。 它是一个习惯很长一段时间。 然后我find了。 我真的注意到速度差异。 在加载innerhtml花了一段时间来更新,然而通过addElement它的瞬间!

为了回应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中的节点,它在尝试访问父节点时返回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 ); 

我发现这个方法在replace元素内部的string时非常有用,如果不确定节点将包含什么内容,而不是担心如何清理混乱,请重新开始。

通常,JavaScript使用数组来引用DOM节点的列表。 所以,如果你有兴趣通过HTMLElements数组来完成这个工作,这将会很好地工作。 另外,值得注意的是,因为我使用的是数组引用而不是JavaScript proto,所以应该在任何浏览器(包括IE)中工作。

 while(nodeArray.length !== 0) { nodeArray[0].parentNode.removeChild(nodeArray[0]); } 

在jQuery中,你只需要使用这个:

 $("#target").empty(); 

示例代码:

 $("#button").click(function(){ $("#target").empty(); }); 

这是一个纯粹的JavaScript我使用不是jQuery,但在所有浏览器甚至IE浏览器

 <div id="my_div"> <p>i am the first child</p> <p>i am another paragraphs</p> <p>enven me also i am another paragraphs</p> </div> <button id ="my_button>Remove nodes ?</button> document.getElementById("my_button").addEventListener("click",function(){ let parent_node =document.getElemetById("my_div"); let last_child =parent_node.lastChild; while(last_child){ parent_node.removeChild(last_child); } }) 

或者你可以简化这个

 document.getElementById("my_button").addEventListener("click",function(){ let parent_node =document.getElemetById("my_div"); parent_node.innerHTML =""; }) 

如果你想把东西放回那个divinnerHTML可能会更好。

我的例子:

 <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(""); 

根本只有IE:

 parentElement.removeNode(true); 

true – 意味着深度去除 – 这意味着所有的孩子也被删除

选项2从获胜的答案 。

 function emptyElement(element) { var myNode = element; while (myNode.firstChild) { myNode.removeChild(myNode.firstChild); } } emptyElement(document.body) 

与jQuery:

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