按ID删除元素


1128

使用标准JavaScript删除元素时,必须首先转到其父元素:

var element = document.getElementById("element-id");
element.parentNode.removeChild(element);

首先不得不去父节点对我来说有点奇怪,JavaScript是否有这样的原因?


534
如James所说,DOM不支持直接删除对象。您必须转到其父级并将其从那里删除。Javascript不会让某个元素自杀,但是它确实允许杀婴……
Mark Henderson

21
有什么原因吗?理查德•费曼(Richard Feynman)拒绝。(那么,如果您编写了任何树形结构程序,技术理由就很容易看出。孩子必须以任何方式通知父级否则树形结构可能会被破坏。由于它必须在内部进行,所以如果它提供了一个单行功能,这对您来说也很方便,您也可以定义自己。)
kizzx2 2012年

6
我看到的唯一原因是xml / xhtml文档中应该始终有一个根元素,因此您将无法删除它,因为它没有父元素
Alex K

5
我非常喜欢Johan的解决方法,但不确定为什么这些功能不是本机提供的。如观众数量所示,这是非常常见的操作。
Zaz

12
element.remove()从ES5开始,您可以直接使用。你不需要父母!
Gibolt

Answers:


659

我知道,增强本机DOM功能并不总是最好的或最受欢迎的解决方案,但是对于现代浏览器来说,这很好。

Element.prototype.remove = function() {
    this.parentElement.removeChild(this);
}
NodeList.prototype.remove = HTMLCollection.prototype.remove = function() {
    for(var i = this.length - 1; i >= 0; i--) {
        if(this[i] && this[i].parentElement) {
            this[i].parentElement.removeChild(this[i]);
        }
    }
}

然后您可以删除这样的元素

document.getElementById("my-element").remove();

要么

document.getElementsByClassName("my-elements").remove();

注意:此解决方案不适用于IE 7及更低版本。有关扩展DOM的更多信息,请阅读本文

编辑:回顾我在2019年的答案,node.remove()可以进行救援,并且可以如下使用(没有上面的polyfill):

document.getElementById("my-element").remove();

要么

[...document.getElementsByClassName("my-elements")].map(n => n && n.remove());

这些功能在所有现代浏览器(不是IE)中都可用。阅读有关MDN的更多信息。


3
不应该是[document.getElementsByClassName(“ my-elements”)[0] .remove(); ]我认为函数remove()不能由数组实现。为了删除类的所有元素或返回数组的任何选择器,您必须遍历所有元素并在每个元素上调用remove()。
Sedat Kilinc 2014年

1
@SedatKilinc,您尝试过实际的代码段吗?没有涉及数组,而是NodeList或是HTMLCollection类似数组的元素集。第二种方法定义允许删除这些“元素集”。
Johan Dettmar

1
在chrome控制台中运行该命令似乎仅一次删除一个元素document.getElementsByClassName("my-elements").remove();。编辑:实际上,它删除了一堆,但需要重新运行才能完成。在此页面上使用“ comment-copy”类进行尝试。
DanielST 2015年

2
@slicedtoad你是对的,我不好。我修改了该函数以使这些元素向后循环。似乎工作正常。您正在谈论的行为很可能是由更新索引引起的。
Johan Dettmar

1
不要这样 只需按照语言意图删除项目。任何熟悉XML解析的人都会认识到有必要联系父级来删除子级。HTML是XML的超集。
Hal50000 '16

283

跨浏览器和IE> = 11:

document.getElementById("element-id").outerHTML = "";

3
这似乎是最简单,最可靠和最快的解决方案。我不需要删除该元素,因此我跳过了最后一行,但是无论如何都不会增加任何开销。。注意:我在尝试寻找比$.readyjs 更快的noscript标记替代品时发现了这一点。为了按需要使用它,我必须将其包装在1ms setTimeout函数中。这可以立即解决我所有的问题。格拉西亚斯。
dgo 2014年

请记住outerHTML,该标准仍然是新的内容。如果在撰写本文时正在寻求对任何版本> 6的软件的支持,则需要其他解决方案。remove其他人提到的功能是类似的情况。和往常一样,实现polyfill是安全的。
超级猫

delete element什么也不做,因为你不能在JS删除变量,只有钥匙;)检查自己这是行不通的console.log(element)delete element...
伊万Kleshnin

2
这比removeChild(在我的系统上大约6-7%)要慢一些。参见jsperf.com/clear-outerhtml-v-removechild/2
AlejandroGarcíaIglesias

1
如果这是您要删除的内容,则可能会留出一个iframe所在的空间。
lacostenycoder

164

您可以创建一个remove函数,这样您就不必每次都考虑它:

function removeElement(id) {
    var elem = document.getElementById(id);
    return elem.parentNode.removeChild(elem);
}

12
如果您希望单线而不走全球路线,则可以更改elemremove.elem。这样,函数将引用自身,因此您不必创建另一个全局变量。:-)
twiz

4
那么,为什么需要返回元素?为什么不呢function remove(id) { document.getElementById(id).parentNote.removeChild(document.getElementById(id)); }
Zach Lysobey 2013年

4
@ZachL:虽然您的解决方案似乎更明显,但它执行两次DOM查找,速度较慢,而其他解决方案似乎希望避免这种情况。
Wk_of_Angmar

3
不起作用。错误太多。这有效:var elem = document.getElementById('id'); elem.parentNode.removeChild(elem);
米奇比赛

2
哇,为什么这么复杂。只需将元素本身传递给函数,而不是ID字符串即可。这样,元素在整个功能中都是可访问的,而且它保持一个衬里
DavidFariña16

97

这就是DOM支持的内容。在该页面上搜索“删除”或“删除”,removeChild是唯一删除节点的页面。


13
那回答了我最初的问题,但是JavaScript为什么如此工作?
Zaz

5
我只是在猜测,但是我认为这与内存管理有关。父节点很可能持有指向子节点的指针的列表。如果仅删除一个节点(不使用父节点),则父节点仍将保留指针并导致内存泄漏。因此,api会强制您在父级上调用函数以删除子级。这也很好,因为它可以使树向下通过子节点,并在每个子节点上调用remove,而不会泄漏内存。
Chadams

2
大家好,即使该参考文献没有此内容,我还是偶然发现了它。写作element.remove();会起作用。也许这是新事物。但是第一次对我来说,它有效。我认为它应该一直有效,因为它是非常基本的东西。
穆罕默德·乌默

1
但它在IE7及以下版本中不起作用。从IE7及更低版本开始,remove()不起作用
fanfan1609 2014年

1
如果我不得不猜测的话,它之所以如此工作是因为DOM元素无法删除自己。您正在从脚下移走那块众所周知的地毯。您必须将其从容器中删除。至少我就是这样想的。
PhilT

82

DOM以节点树的形式组织,其中每个节点都有一个值,以及对其子节点的引用列表。因此,可以element.parentNode.removeChild(element)精确地模拟内部发生的情况:首先转到父节点,然后删除对子节点的引用。

从DOM4开始,提供了一个辅助函数来执行相同的操作:element.remove()。此功能可在87%的浏览器中使用(截至2016年),但不适用于IE11。如果需要支持旧版浏览器,则可以:


2
请不要“修改本机DOM函数”
Emile Bergeron '18

36

要删除一个元素:

 var elem = document.getElementById("yourid");
 elem.parentElement.removeChild(elem);

为了删除所有具有特定类名的元素:

 var list = document.getElementsByClassName("yourclassname");
 for(var i = list.length - 1; 0 <= i; i--)
 if(list[i] && list[i].parentElement)
 list[i].parentElement.removeChild(list[i]);

现有答案很好地覆盖了这一点。
KyleMit 2014年

4
+1对于通过类名删除的简单示例。其他答案并不能很好地解决这一问题
路易丝·埃格尔顿

为什么if(list[i] && list[i].parentElement)需要线?是否由getElementsByClassName方法返回的事实不能保证每个元素的存在?
2014年

不幸的是,就我所知,并不能真正保证存在,但我不知道有关它的细节。我刚刚经历过一些奇怪的未定义或null值,因此将该检查放在这里,而无需进一步调查。所以这有点hack。
csjpeter 2014年

应该是document.getElementsByClassName(...
工人2015年

21

你可以用 element.remove()


13
element.remove()是无效的JavaScript,仅在某些浏览器(例如Chrome)中有效
2014年

4
Josh,它是有效的JavaScript,只有Firefox和Chrome实施了它(请参见MDN)
Tim Nguyen

10
我不好的element.remove() 是,带有DOM4的有效JavaScript可以在所有现代浏览器中正常工作,当然Internet Explorer除外。
Zaz 2014年

24
在FireFox和Chrome上可以正常工作。谁在乎IE
Arun Sharma 2014年

13
有工作的人关心IE!
sqram 2015年

18

ChildNode.remove()方法从对象所属的树中删除该对象。

https://developer.mozilla.org/zh-CN/docs/Web/API/ChildNode/remove

这是一个小提琴,显示了您如何打电话 document.getElementById('my-id').remove()

https://jsfiddle.net/52kp584L/

**

无需扩展NodeList。它已经被实施。

**


2
请注意,任何版本的IE均不支持此功能!
MacroMan

1
如果您仍在为IE开发,我为您感到非常抱歉。
Alex Fallenstedt

您不为IE开发?对于您的客户或客户,我感到非常抱歉。
MacroMan '18

13

您可以使用以下方法直接删除该元素 remove() DOM方法。

这是一个例子:

let subsWrapper = document.getElementById("element_id");
subsWrapper.remove();
//OR directly.
document.getElementById("element_id").remove();


7

首先不得不去父节点对我来说有点奇怪,JavaScript是否有这样的原因?

函数名称为removeChild(),在没有父项的情况下如何删除子项?:)

另一方面,您不必总是像显示的那样调用它。 element.parentNode只是获得给定节点的父节点的助手。如果您已经知道父节点,则可以像这样使用它:

例如:

// Removing a specified element when knowing its parent node
var d = document.getElementById("top");
var d_nested = document.getElementById("nested");
var throwawayNode = d.removeChild(d_nested);

https://developer.mozilla.org/zh-CN/docs/Web/API/Node/removeChild

================================================== =======

要添加更多内容:

一些答案指出parentNode.removeChild(child);,可以使用代替使用elem.remove();。但是,正如我已经注意到的,这两个功能之间存在差异,并且在这些答案中并未提及。

如果使用removeChild(),它将返回对已删除节点的引用。

var removedChild = element.parentNode.removeChild(element); 
console.log(removedChild); //will print the removed child.

但是,如果您使用elem.remove();,它将不会返回参考。

var el = document.getElementById('Example');
var removedChild = el.remove(); //undefined

https://developer.mozilla.org/zh-CN/docs/Web/API/ChildNode/remove

在Chrome和FF中可以观察到此行为。我相信这是值得注意的:)

希望我的回答为问题增加一些价值,并会有所帮助!!


6

使用ele.parentNode.removeChild(ele)的函数不适用于您创建但尚未插入HTML的元素。像jQuery和Prototype这样的库明智地使用了如下所示的方法来规避该限制。

_limbo = document.createElement('div');
function deleteElement(ele){
    _limbo.appendChild(ele);
    _limbo.removeChild(ele);
}

我认为JavaScript的工作原理是这样的,因为DOM的原始设计者将父/子和上一个/下一个导航作为优先级,而不是当今流行的DHTML修改。在90年代中期,能够动态读取整个HTML表单或交互式GUI元素的瞬间,能够从DOM中的相对位置读取一个<input type ='text'>并写入另一个对象非常有用。一些开发人员的眼睛。


3

首先不得不去父节点对我来说有点奇怪,JavaScript是否有这样的原因?

恕我直言:这样做的原因与我在其他环境中看到的相同:您正在基于与某物的“链接”执行操作。链接到它后就无法删除它。

像砍树枝一样。砍伐时坐在最靠近树的一侧,否则结果...很不幸(虽然很有趣)。


2

这实际上来自FireFox。。。有一次,IE领先于众包,并允许直接删除元素。

这只是我的假设,但我认为您必须通过父母删除孩子的原因是由于FireFox处理引用的方式存在问题。

如果您调用一个对象直接提交hari-kari,则在该对象死亡后,您仍将保留对该对象的引用。这可能会产生一些令人讨厌的错误……例如无法将其删除,将其删除但保留对其有效的引用,或者仅仅是内存泄漏。

我相信,当他们意识到这个问题时,解决方法是通过其父元素删除一个元素,因为当元素消失时,您现在只是持有对父元素的引用。这样可以消除所有的不愉快,并且(例如,如果逐个节点关闭一个树节点)将相当不错。

它应该是一个易于修复的错误,但是与Web编程中的许多其他事情一样,该版本可能很着急,导致了这一问题……而到下一个版本问世时,已经有足够的人使用它来更改它破坏一堆代码。

同样,所有这些只是我的猜测。

但是,我确实期待着Web编程最终得到全面的清理的一天,所有这些奇怪的小特质都得到了清理,每个人都开始遵循相同的规则。

大概是在我的机器人仆人起诉我后退工资的第二天。


10
我怀疑Firefox对此负责。removeChildDOM Level 1 Node接口的一种方法。
Felix Kling


0
// http://javascript.crockford.com/memory/leak.html
// cleans dom element to prevent memory leaks
function domPurge(d) {
    var a = d.attributes, i, l, n;
    if (a) {
        for (i = a.length - 1; i >= 0; i -= 1) {
            n = a[i].name;
            if (typeof d[n] === 'function') {
                d[n] = null;
            }
        }
    }
    a = d.childNodes;
    if (a) {
        l = a.length;
        for (i = 0; i < l; i += 1) {
            domPurge(d.childNodes[i]);
       }
    }
}

function domRemove(id) {
    var elem = document.getElementById(id);
    domPurge(elem);
    return elem.parentNode.removeChild(elem);
}

-3

这是删除没有脚本错误的元素的最佳功能:

function Remove(EId)
{
    return(EObj=document.getElementById(EId))?EObj.parentNode.removeChild(EObj):false;
}

请注意EObj=document.getElementById(EId)

这不是一个等号==

如果element EId存在,则函数将其删除,否则返回false,而不是error


4
创建一个全局变量。
bjb568 2014年

1
这也是另一个答案的最差版本,但是晚了两年。
Emile Bergeron
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.