在JavaScript中删除DOM节点的所有子元素
我将如何在JavaScript中删除DOM节点的所有子元素?
说我有以下(丑陋的)HTML:
hello
world
我抓住了我想要的节点:
var myNode = document.getElementById("foo");
我如何删除removeElement的子女,只留下
我可以这样做:
myNode.childNodes = new Array();
或者我应该使用removeElement的某些组合?
我希望答案是直接的DOM; 如果您还提供jQuery中的答案以及仅限DOM的答案,那么可以提供额外的分数。
26个解决方案
1244 votes
选项1(慢得多,见下面的评论):
var myNode = document.getElementById("foo");
myNode.innerHTML = '';
选项2(快得多):
var myNode = document.getElementById("foo");
while (myNode.firstChild) {
myNode.removeChild(myNode.firstChild);
}
Gabriel McAdams answered -01-21T02:05:02Z
82 votes
目前接受的答案是关于innerHTML较慢(在IE和Chrome中至少)的错误,正如m93a正确提到的那样。
使用此方法可以大大加快Chrome和FF的速度(这会破坏附加的jquery数据):
var cNode = node.cloneNode(false);
node.parentNode.replaceChild(cNode ,node);
在FF和Chrome的遥远的第二,在IE中最快:
node.innerHTML = '';
InnerHTML不会破坏你的事件处理程序或破坏jquery引用,它也建议在这里作为解决方案:[/en-US/docs/Web/API/Element.innerHTML]
最快的DOM操作方法(仍比前两个慢)是Range删除,但IE9之前不支持范围。
var range = document.createRange();
range.selectNodeContents(node);
range.deleteContents();
提到的其他方法似乎具有可比性,但比innerHTML慢很多,除了异常值,jquery(1.1.1和3.1.1),它比其他任何方法慢得多:
$(node).empty();
证据在这里:
[/innerhtml-vs-removechild/167] [/innerhtml-vs-removechild/300][/remove-all-child-elements-of-a-dom-node-in-javascript](jsperf重启的新url,因为编辑旧的url不起作用)
Jsperf的“per-test-loop”通常被理解为“per-iteration”,只有第一次迭代才有删除的节点,因此结果毫无意义,在发布时,此线程中的测试设置不正确。
npjohns answered -01-21T02:06:16Z
40 votes
var myNode = document.getElementById("foo");
var fc = myNode.firstChild;
while( fc ) {
myNode.removeChild( fc );
fc = myNode.firstChild;
}
如果你有可能有jQuery受影响的后代,那么你必须使用一些方法来清理jQuery数据。
$('#foo').empty();
jQuery DOM方法将确保清除与要删除的元素关联的jQuery的任何数据。
如果您只是使用DOM删除子项的方法,则该数据将保留。
user113716 answered -01-21T02:06:51Z
31 votes
如果你使用jQuery:
$('#foo').empty();
如果你不这样做:
var foo = document.getElementById('foo');
while (foo.firstChild) foo.removeChild(foo.firstChild);
PleaseStand answered -01-21T02:07:18Z
15 votes
最快的...
var removeChilds = function (node) {
var last;
while (last = node.lastChild) node.removeChild(last);
};
感谢Andrey Lushnikov与(酷网站!)的链接。
Gabe Halsmer answered -01-21T02:07:47Z
15 votes
使用现代的Javascript,与remove!
const parent = document.getElementById("foo");
while (parent.firstChild) {
parent.firstChild.remove();
}
这是在ES5中编写节点删除的更新方法。 它是vanilla JS,读起来比以前的版本好多了。
大多数用户应该使用现代浏览器,或者您可以根据需要进行调整。
浏览器支持 - 4月91%
Gibolt answered -01-21T02:08:27Z
9 votes
如果您只想让节点没有子节点,您也可以像这样复制它:
var dupNode = document.getElementById("foo").cloneNode(false);
取决于你想要实现的目标。
DanMan answered -01-21T02:08:56Z
5 votes
element.textContent = '';
它就像innerText,标准除外。 它比removeChild()慢一点,但它更容易使用,如果你没有太多东西要删除,也不会产生很大的性能差异。
bjb568 answered -01-21T02:09:18Z
5 votes
这是另一种方法:
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();
}
Nathan K answered -01-21T02:09:35Z
4 votes
回应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 );
我发现这个方法在替换元素内部的字符串时非常有用,如果你不确定节点将包含什么,而不是担心如何清理混乱,那就开始新鲜了。
jeroen answered -01-21T02:10:10Z
3 votes
有几种方法可以实现这一目标:
最快的 ():
while (node.lastChild) {
node.removeChild(node.lastChild);
}
替代方案(较慢):
while (node.firstChild) {
node.removeChild(node.firstChild);
}
while (node.hasChildNodes()) {
node.removeChild(node.lastChild);
}
使用建议的选项进行基准测试
magiccrafter answered -01-21T02:10:50Z
3 votes
我看到有人这样做:
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。 这是一个习惯很长一段时间。 然后我发现了这个。 我实际上注意到速度差异。 在加载时,innerhtml需要一段时间来更新,但是它会立即通过addElement进行更新!
Noitidart answered -01-21T02:11:39Z
3 votes
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
}
}
}
这将删除元素中的所有节点。
Henrik answered -01-21T02:12:00Z
2 votes
innerText是赢家! [/innerhtml-vs-removechild/133。]在所有先前的测试中,父节点的内部dom在第一次迭代时被删除,然后是innerHTML或removeChild,其中应用于空div。
Alexey answered -01-21T02:12:23Z
2 votes
通过Javascript删除节点的子节点的最简单方法
var myNode = document.getElementById("foo");
while(myNode.hasChildNodes())
{
myNode.removeChild(myNode.lastChild);
}
Chaitanya Bapat answered -01-21T02:12:44Z
1 votes
通常,JavaScript使用数组来引用DOM节点列表。 因此,如果您有兴趣通过HTMLElements数组执行此操作,这将很有效。 此外,值得注意的是,因为我使用数组引用而不是JavaScript proto,这应该适用于任何浏览器,包括IE。
while(nodeArray.length !== 0) {
nodeArray[0].parentNode.removeChild(nodeArray[0]);
}
r00t hkr answered -01-21T02:13:07Z
0 votes
为什么我们不遵循这里最简单的方法“删除”循环内部。
const foo = document.querySelector(".foo");
while (foo.firstChild) {
foo.firstChild.remove();
}
选择父div
在While循环中使用“remove”方法来消除第一个子元素,直到没有剩下。
NEelansh VErma answered -01-21T02:13:41Z
0 votes
这是我通常做的事情:
HTMLElement.prototype.empty = function() {
while (this.firstChild) {
this.removeChild(this.firstChild);
}
}
瞧,以后你可以用以下方法清空任何dom元素:
anyDom.empty()
Ado Ren answered -01-21T02:14:09Z
-1 votes
jQuery中的其他方法
var foo = $("#foo");
foo.children().remove();
or
$("*", foo ).remove();
or
foo.html("");
Anoop answered -01-21T02:14:31Z
-1 votes
只是IE:
parentElement.removeNode(true);
true - 深度去除的方法 - 这意味着所有孩子也被移除
user2656596 answered -01-21T02:14:59Z
-1 votes
最简单的方法:
let container = document.getElementById("containerId");
container.innerHTML = "";
milosz answered -01-21T02:15:16Z
-1 votes
简单快速的循环使用!!
var myNode = document.getElementById("foo");
for(var i = myNode.childNodes.length - 1; i >= 0; --i) {
myNode.removeChild(myNode.childNodes[i]);
}
这将不适用于标签!
MOHIT KARKAR answered -01-21T02:15:44Z
-1 votes
刚看到有人在另一个问题中提到这个问题,并认为我会添加一个我还没看到的方法:
function clear(el) {
el.parentNode.replaceChild(el.cloneNode(false), el);
}
var myNode = document.getElementById("foo");
clear(myNode);
clear函数使用元素并使用父节点将其自身替换为没有子元素的副本。 如果元素稀疏,但是当元素具有一堆节点时,性能增益得以实现,性能增益不大。
Harry Chilinguerian answered -01-21T02:16:13Z
-3 votes
如果你想把东西放回.firstChild,那么.lastChild可能更好。
我的例子:
function displayHTML(result){
var movieLink = document.createElement("li");
var t = document.createTextNode(result.Title);
movieLink.appendChild(t);
outputDiv.appendChild(movieLink);
}
如果我使用.firstChild或.lastChild方法,则displayHTML()函数不起作用,但.innerHTML方法没有问题。
Bjathr answered -01-21T02:16:48Z
-3 votes
这是一个纯粹的javascript我不使用jQuery但在所有浏览器甚至IE中工作,它很容易理解
Paragraph one
Paragraph two
Paragraph three
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 ="";
})
Ir Calif answered -01-21T02:17:10Z
-5 votes
用jQuery:
$("#foo").find("*").remove();
Arnaud F. answered -01-21T02:17:32Z