我如何在JavaScript中删除DOM节点的所有子元素?
说我有以下(丑陋的)HTML:
<p id="foo">
<span>hello</span>
<div>world</div>
</p>
我 grab 了我想要的节点:
var myNode = document.getElementById("foo");
我怎么能删除 foo
的子项以便只留下 <p id="foo"></p>
?
我能这样做吗:
myNode.childNodes = new Array();
或者我应该使用 removeElement
的某些组合?
我希望答案是直接的DOM;如果您还在jQuery中提供答案以及仅限DOM的答案,那么可以获得额外的分数 .
27 回答
使用现代Javascript,删除!
这是在ES5中编写节点删除的更新方法 . 它是vanilla JS,读起来比以前的版本好多了 .
大多数用户应该使用现代浏览器,或者您可以根据需要进行调整 .
Browser Support - 2018年4月91%
如果您只想让节点没有子节点,您也可以像这样复制它:
取决于你想要实现的目标 .
我看到有人这样做:
然后有人说使用
el.lastNode
更快但我认为这是最快的:
你怎么看?
ps:这个话题对我来说是一个救生员 . 我的firefox插件被拒绝了因为我使用了innerHTML . 这是一个很长一段时间的习惯 . 那我就知道了 . 我实际上注意到速度差异 . 在加载时,innerhtml需要一段时间来更新,但是它会立即通过addElement进行更新!
只是IE:
true
- 意味着深度删除 - 这意味着所有孩子也被删除通过Javascript删除节点的子节点的最简单方法
最简单的方法:
为什么我们不遵循这里最简单的方法“删除”循环内部 .
选择父div
在While循环中使用"remove"方法消除第一个子元素,直到没有剩余 .
如果你有可能有jQuery受影响的后代,那么你必须使用一些方法来清理jQuery数据 .
The jQuery .empty() method将确保清除与要删除的元素关联的jQuery的任何数据 .
如果您只是使用
DOM
方法删除子项,则该数据将保留 .最快的...
感谢Andrey Lushnikov为his link to jsperf.com(很酷的网站!) .
这将删除元素中的所有节点 .
有几种方法可以实现这一目标:
最快的 ():
替代方案(较慢):
Benchmark with the suggested options
通常,JavaScript使用数组来引用DOM节点列表 . 因此,如果您有兴趣通过HTMLElements数组执行此操作,这将很有效 . 另外,值得注意的是,因为我使用的是数组引用而不是JavaScript proto,所以这应该适用于任何浏览器,包括IE .
innerText是赢家! http://jsperf.com/innerhtml-vs-removechild/133 . 在所有先前的测试中,父节点的内部dom在第一次迭代时被删除,然后是innerHTML或removeChild,其中应用于空div .
用jQuery:
jQuery中的其他方法
这是一个纯javascript我不使用jQuery但在所有浏览器甚至IE中工作,它很容易理解
这是另一种方法:
这是我通常做的事情:
瞧,以后你可以用以下方法清空任何dom元素:
刚看到有人在另一个问题中提到这个问题,并认为我会添加一个我还没看到的方法:
clear函数使用元素并使用父节点将其自身替换为没有子元素的副本 . 如果元素稀疏,但是当元素具有一堆节点时,性能增益得以实现,性能增益不大 .
它's like innerText, except standard. It'比
removeChild()
,但如果你没有太多东西需要删除,那么's easier to use and won' t会产生很大的性能差异 .回应DanMan,Maarten和Matt . 克隆节点,设置文本确实是我的结果中可行的方法 .
这也适用于不在dom中的节点,当尝试访问parentNode时返回null . 此外,如果您需要保证安全,节点在添加内容之前是空的,这非常有用 . 考虑下面的用例 .
我发现这个方法在替换元素中的字符串时非常有用,如果你不确定节点将包含什么,而不是担心如何清理混乱,那么就开始新鲜了 .
如果你想把某些东西放回
div
,innerHTML
可能会更好 .我的例子:
如果我使用
.firstChild
或.lastChild
方法,之后displayHTML()
函数不起作用,但.innerHTML
方法没有问题 .如果你使用jQuery:
如果你不这样做:
选项1(慢得多,见下面的评论):
选项2(很多快点):
使用范围循环对我来说是最自然的:
根据我在Chrome和Firefox中的测量结果,它慢了1.3倍 . 在正常情况下,这可能无关紧要 .
简单快速的循环使用!!
这在
<span>
标签中不起作用!目前接受的答案是关于innerHTML较慢(在IE和Chrome中至少)的错误,正如m93a正确提到的那样 .
使用此方法可以大大加快Chrome和FF的速度(这会破坏附加的jquery数据):
在FF和Chrome的遥远的第二,在IE中最快:
InnerHTML won't destroy your event handlers or break jquery references ,这里也建议作为解决方案:https://developer.mozilla.org/en-US/docs/Web/API/Element.innerHTML
最快的DOM操作方法(仍然比前两个慢)是Range删除,但IE9之前不支持范围 .
提到的其他方法似乎具有可比性,但比innerHTML慢很多,除了异常值,jquery(1.1.1和3.1.1),它比其他任何方法慢得多:
证据在这里:
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重启的新网址,因为编辑旧网址不起作用)
Jsperf的“per-test-loop”通常被理解为“per-iteration”,只有第一次迭代才有删除的节点,因此结果毫无意义,在发布时,此线程中的测试设置不正确 .