ChatGPT解决这个技术问题 Extra ChatGPT

按 id 移除元素

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

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

必须先转到父节点对我来说似乎有点奇怪,JavaScript 这样工作是否有原因?

正如 James 所说,DOM 不支持直接删除对象。你必须去它的父母那里把它从那里删除。 Javascript 不会让元素自杀,但它确实允许杀婴......
有原因吗? Richard Feynman says no。 (好吧,技术上的理由很容易看出你是否编写了任何树结构程序。孩子必须通知父母无论如何否则树结构可能会被破坏。因为无论如何它必须在内部完成,如果它为你提供了一个单行函数,对你来说只是一个方便的函数,你可以自己定义。)
我看到的唯一原因是 xml/xhtml 文档中应该始终有一个根元素,因此您将无法删除它,因为它没有父元素
我非常喜欢 Johan's workaround,但我不确定为什么这些功能不是原生提供的。从观看人数来看,这是一种非常普遍的操作。
从 ES5 开始,您可以直接使用 element.remove()。你不需要父母!

J
Johan Dettmar

我知道增强原生 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 的更多信息,请阅读此 article

编辑:回顾我在 2019 年的回答,node.remove() 来救援,可以按如下方式使用(没有上面的 polyfill):

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

或者

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

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


不应该是 [ document.getElementsByClassName("my-elements")[0].remove(); ] 我认为函数 remove() 不是由数组实现的。为了删除类的所有元素或返回数组的任何选择器,您必须遍历所有元素并在每个元素上调用 remove()。
@SedatKilinc,您尝试过实际的片段吗?不涉及数组,而是 NodeListHTMLCollection,它们是类似数组的元素集。第二种方法定义允许删除这些“元素集”。
在使用 document.getElementsByClassName("my-elements").remove(); 时,在 chrome 控制台中运行它似乎一次只删除一个元素。编辑:实际上它删除了一堆,但需要重新运行才能完成。在这个页面上用“comment-copy”类试试。
@slicedtoad 你是对的,我的错。我修改了函数以向后循环元素。似乎工作正常。您正在谈论的行为很可能是由更新的索引引起的。
不要这样做。只需按照语言的意图删除项目。任何熟悉解析 XML 的人都会认识到需要到达父级以删除子级。 HTML 是 XML(某种意义上)的超集。
m
mb21

跨浏览器和 IE >= 11:

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

这似乎是最简单、最可靠、最快的解决方案。我不需要删除该元素,因此我跳过了最后一行,但这不应该增加任何开销。注意:我在尝试找到比 $.ready 更快的元素时发现了这一点js 替代 noscript 标记。为了以我想要的方式使用它,我必须将它包装在一个 1ms setTimeout 函数中。这一下子解决了我所有的问题。格拉西亚斯。
请记住,outerHTML 仍然是标准的新(更)补充。如果您在撰写本文时正在寻求对任何软件的支持 >6,您将需要另一种解决方案。别人提到的remove函数就是一个类似的例子。像往常一样,实现 polyfill 是安全的。
这比 removeChild 慢一点(在我的系统上大约是 6-7%)。请参阅jsperf.com/clear-outerhtml-v-removechild/2
如果这是您要删除的内容,这可能会留下 iframe 曾经所在的空间。
嘿@dgo,你摇滚!
S
Sarkar

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

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

如果您想要单行而不是全局,您可以将 elem 更改为 remove.elem。这样函数引用自身,因此您不必创建另一个全局变量。 :-)
那么,为什么需要返回元素呢?为什么不function remove(id) { document.getElementById(id).parentNote.removeChild(document.getElementById(id)); }
@ZachL:虽然您的解决方案可能看起来更明显,但它执行两个较慢的 DOM 查找,并且其他解决方案似乎想要避免。
不工作。错误太多。这有效: var elem = document.getElementById('id') ; elem.parentNode.removeChild(elem);
哇,怎么这么复杂。只需将元素本身传递给函数而不是 id 字符串。通过这种方式,元素可以在整个函数中访问,而且它保持单线
K
KyleMit

2011 年更新

这已添加到 DOM spec 后面的 in 2011,因此您可以使用:

element.remove()

DOM 组织在节点树中,其中每个节点都有一个值,以及对其子节点的引用列表。所以 element.parentNode.removeChild(element) 准确地模仿了内部发生的事情:首先您转到父节点,然后删除对子节点的引用。

从 DOM4 开始,提供了一个辅助函数来执行相同的操作:element.remove()。此 works in 96% of browsers(截至 2020 年),但不是 IE 11。

如果您需要支持旧版浏览器,您可以:

通过父节点移除元素

修改本机 DOM 函数,如 Johan Dettmar 的回答,或者

使用 DOM4 polyfill。


请不要“修改原生 DOM 函数”。
C
Christian Sirolli

It's what the DOM supports。在该页面中搜索“删除”或“删除”,removeChild 是唯一删除节点的页面。


这回答了我最初的问题,但为什么 JavaScript 会这样工作?
我只是在这里猜测,但我认为它与内存管理有关。父节点很可能持有指向子节点的指针列表。如果您刚刚删除了一个节点(不使用父节点),父节点仍会持有指针并导致内存泄漏。所以 api 强制你调用父级的函数来删除子级。这也很好,因为它可以通过子节点向下遍历树,并在每个子节点上调用 remove,并且不会泄漏内存。
嘿伙计们,即使那个参考没有这个,我偶然发现它。写 element.remove(); 将起作用。也许这是新事物。但对我来说是第一次,它有效。我认为它应该一直有效,因为它是非常基本的必须具备的东西。
但它在IE7及以下版本中不起作用。从 IE7 及以下版本,remove() 不起作用
如果我不得不猜测,它之所以会这样工作,是因为 DOM 元素无法自行移除。你正在从它的脚下移除众所周知的地毯。您必须将其从容器中移除。至少我是这么想的。
c
csjpeter

删除一个元素:

 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]);

现有答案很好地涵盖了这一点。
+1 对于按类名删除的简单示例。其他答案没有很好地涵盖这一点
为什么需要 if(list[i] && list[i].parentElement) 行? getElementsByClassName 方法返回的事实不是保证每个元素的存在吗?
不幸的是,据我所知并不能真正保证存在,但我不知道它的细节。我刚刚经历了一次奇怪的未定义或空值,我没有进一步调查就将检查放在那里。所以这有点hack。
它应该是 document.getElementsByClassName(...
S
Sai Sunder

你可以使用 element.remove()


element.remove() 不是有效的 JavaScript,仅适用于某些浏览器,例如 Chrome
Josh,它是有效的 javascript,但只有 Firefox 和 Chrome 实现了它(参见 MDN)
我的错,element.remove() is valid JavaScript with DOM4,并且适用于所有现代浏览器,当然 Internet Explorer 除外。
在 FireFox 和 Chrome 上运行良好。谁在乎IE
有工作的人关心IE!
C
Code Cooker

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

这是一个例子:

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

A
Alex Fallenstedt

ChildNode.remove() 方法将对象从其所属的树中移除。

https://developer.mozilla.org/en-US/docs/Web/API/ChildNode/remove

这是一个显示如何调用 document.getElementById('my-id').remove() 的小提琴

https://jsfiddle.net/52kp584L/

**

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

**


请注意,任何版本的 IE 都不支持此功能!
如果你还在为 IE 开发,我为你感到非常抱歉。
你不是为IE开发的吗?我为您的客户或顾客感到非常抱歉。
现在 IE 已经死了,现在还活着是什么时候。如果你还在为它开发,我为你感到难过。
R
Red

根据当前正在开发的版本 DOM 4 级规范,有一些新的方便的变异方法可用:append()prepend()before()after()replace()remove()

https://catalin.red/removing-an-element-with-plain-javascript-remove-method/


N
Nimeshka Srimal

必须先转到父节点对我来说似乎有点奇怪,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/en-US/docs/Web/API/Node/removeChild

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

要添加更多内容:

一些答案指出,您可以使用 elem.remove(); 而不是使用 parentNode.removeChild(child);。但是正如我所注意到的,这两个功能之间存在差异,并且这些答案中没有提到。

如果您使用 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/en-US/docs/Web/API/ChildNode/remove

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

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


A
Alex

使用 ele.parentNode.removeChild(ele) 的函数不适用于您已创建但尚未插入 HTML 的元素。 jQueryPrototype 之类的库明智地使用如下方法来规避该限制。

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

我认为 JavaScript 之所以如此工作,是因为 DOM 的原始设计者将父/子和上一个/下一个导航视为比当今如此流行的 DHTML 修改更高的优先级。能够从一个 <input type='text'> 读取并通过 DOM 中的相对位置写入另一个在 90 年代中期很有用,当时整个 HTML 表单或交互式 GUI 元素的动态生成在某些开发人员的眼中几乎是一闪而过眼睛。


D
David Buck

你可以简单地使用

document.getElementById("elementID").outerHTML="";

它适用于所有浏览器,甚至在 Internet Explorer 上。


K
Kamil Kiełczewski

最短的

我改进了 Sai Sunder answer,因为 OP 使用允许避免 getElementById 的 ID:

elementId.remove();

box2.remove(); // 移除 BOX 2 this["box-3"].remove(); // 移除 BOX 3(对于带有 'minus' 字符的 Id)

My BOX 1
My BOX 2
我的盒子 3
我的盒子 4


T
TheSatinKnight

必须先转到父节点对我来说似乎有点奇怪,JavaScript 这样工作是否有原因?

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

就像砍树枝一样。切割时坐在离树最近的一侧,否则结果将是……不幸(虽然很有趣)。


J
James

据我了解,直接删除节点在 Firefox 中不起作用,仅在 Internet Explorer 中起作用。所以,要支持 Firefox,你必须去父级删除它的子级。

参考:http://chiragrdarji.wordpress.com/2007/03/16/removedelete-element-from-page-using-javascript-working-in-firefoxieopera/


这并不能真正回答我的问题,而且您链接到的页面提供的解决方案比我的更差。
A
Alex

这个实际上来自 Firefox...有一次,IE 领先于群雄并允许直接删除一个元素。

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

如果你调用一个对象直接提交hari-kari,那么在它死后,你仍然持有对它的引用。这有可能产生一些令人讨厌的错误......例如未能删除它,删除它但保持对它的引用似乎有效,或者只是内存泄漏。

我相信当他们意识到这个问题时,解决方法是通过其父元素删除一个元素,因为当元素消失时,您现在只是持有对父元素的引用。这将停止所有不愉快的事情,并且(例如,如果逐个节点关闭树)'zip-up' 会非常好。

它应该是一个很容易修复的错误,但与 Web 编程中的许多其他事情一样,发布可能很匆忙,导致了这个……当下一个版本出现时,已经有足够多的人在使用它,以至于改变它会导致打破一堆代码。

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

然而,我确实期待 Web 编程最终得到全面大扫除的那一天,所有这些奇怪的小特质都被清理干净,每个人都开始按照相同的规则进行游戏。

可能是在我的机器人仆人起诉我拖欠工资的第二天。


我怀疑Firefox对此负责。 removeChildDOM Level 1 Node interface 的一个方法。
w
will Farrell
// 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);
}

W
Wilk

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

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

请注意 EObj=document.getElementById(EId)

这是一个等号而不是 ==

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


创建一个全局变量。
它也是 another answer 的最差版本,但晚了 2 年。