在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 =""; })
如果你想把东西放回那个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("");
根本只有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();