使用标准javascript删除元素时,必须先转到其父级:
1 2
var element = document.getElementById ( "element-id" ) ;
element.parentNode .removeChild ( element) ;
对于我来说,必须先转到父节点似乎有点奇怪,是否有原因让javascript这样工作?
正如詹姆斯所说,DOM不支持直接删除对象。您必须转到它的父级并将其从那里移除。javascript不会让元素自杀,但它允许杀婴…
到目前为止,我知道,如果您使用的是javascript而不是任何javascript库,那么这是唯一一种跨浏览器删除子元素的方法。
有什么原因吗?理查德·费曼说没有(好吧,技术上的理由很容易看出你是否写过任何树结构程序)。无论如何,子级必须通知父级,否则可能会破坏树结构。因为无论如何,它必须在内部完成,如果它为您提供了一个单行函数,那么对于您来说,它只是一个方便的函数,您也可以定义自己。)
我看到的唯一原因是XML/XHTML文档中应该始终存在根元素,因此您将无法删除它,因为它没有父元素
我很喜欢Johan的解决方案,我不知道为什么这些功能不是本地提供的。从观众的数量来看,这是一个非常常见的操作。
@Kizzx2你的意思是链接到"feynman:f*****"磁铁,它们是如何工作的?因为,嗯,这就是它指向的地方,我在那个关于dom和元素移除的脚本中没有看到任何内容。(好吧,好吧,我明白你的意思了,但我相信磁性远不如JavaScript,它使OP的问题比那个面试官的问题更为可行。^d那是说,诚然,IAnap[物理学家]。)
@拉芬,好吧,你有点读懂了整件事来理解这一点。但基本上,它对"似乎有点奇怪"的部分做出了反应。任何"原因"也会"显得有点奇怪"。有时候世界就是这样。实际的"技术原因"是树结构的东西,但我认为这并不是一个直观的答案,所以在评论中把它放在括号里)
imho:原因和我在其他环境中看到的一样:你在执行一个基于"链接"的操作。当您链接到它时,不能删除它。就像砍掉一根树枝。切割时坐在离树最近的一侧,否则结果会…不幸(尽管很有趣)。
从ES5开始,您可以直接使用element.remove() 。你不需要父母!
@Markhenderson是Prolicide,不是杀婴,顺便说一句,javascript允许通过祖父母进行Parricide。???
这一次有效。我有一个按钮,它创建我想要的元素,然后是一个EvenListener,它监听单击另一个元素,并用这个代码触发一个函数(我还尝试了node.remove(); )。对于这两个代码段,它都是第一次工作,但第二次出现以下错误:第一行是Uncaught TypeError: Cannot read property 'remove' of null ,第二行是at removeElement (script.js:23) ,第二行是at HTMLDivElement.document.getElementById.addEventListener (script.js:36) 。
因此,浏览器第二次突然返回"htmldivelement"(对象),而不是"elemid"。知道发生了什么事吗?
我知道增强本地DOM函数并不总是最好或最流行的解决方案,但对于现代浏览器来说,这很好。
1 2 3 4 5 6 7 8 9 10
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] ) ;
}
}
}
然后你可以删除这样的元素
1
document.getElementById ( "my-element" ) .remove ( ) ;
。
或
1
document.getElementsByClassName ( "my-elements" ) .remove ( ) ;
。
注:此解决方案不适用于IE 7及以下版本。有关扩展DOM的更多信息,请阅读本文。
编辑:回顾我在2019年的回答,node.remove() 已经获救,可按如下方式使用(不含上面的polyfill):
1
document.getElementById ( "my-element" ) .remove ( ) ;
。
或
1
[ ...document .getElementsByClassName ( "my-elements" ) ] .map ( n => n && n.remove ( ) ) ;
。
这些功能在所有现代浏览器(而不是IE)中都可用。阅读有关MDN的更多信息。
我将此标记为已接受的答案,因为我觉得它比以前接受的答案更能为讨论增添内容。
不应该是[document.getElementsByClassName("my elements")[0].remove();]我认为函数remove()不是由数组实现的。为了删除类的所有元素或返回数组的任何选择器,必须遍历所有元素并对每个元素调用remove()。
@Sedatkilinc,你试过真正的片段了吗?没有涉及到数组,而是NodeList 或HTMLCollection ,它们是类似于数组的元素集。第二个方法定义允许删除这些"元素集"。
在chrome控制台中运行这个命令,在使用document.getElementsByClassName("my-elements").remove(); 时,似乎一次只删除一个元素。编辑:实际上它删除了一堆,但需要重新运行才能完成。在这个页面上用类"comment copy"尝试一下。
@你说得对,我的错。我修改了函数,使其在元素之间向后循环。似乎工作得很好。您所说的行为很可能是由更新的索引引起的。
@Johandetmar啊,这是有道理的。
那while(this.length){ this[0].parentElement.removeChild(this[0]); } 呢?
@奥雷利亚诺法苏,这可能也可以工作(还没有测试过自己)。但是,这个循环每次都会读取长度值,这可能会稍慢一些。而且据我所知,您还需要if(this[i] && this[i].parentElement) 来确保当前元素仍然存在并且有父元素,否则您可能会收到嵌套元素引发的错误等。
不要这样做。只需按照语言的意图删除项目即可。任何熟悉XML解析的人都会认识到需要访问父级以删除子级。HTML是XML的超集(有点像)。
当使用类似dhtmlx套件的框架时尤其有用,特别是当您在标签栏中有多个具有相同名称和ID的表单,并且您试图实现Ajax时。将此项粘贴到每个表单的顶部,以使以前加载的表单无效,以便当前表单是唯一加载的表单。谢谢!
CrossBrowser和IE>=11:
1
document.getElementById ( "element-id" ) .outerHTML = "" ;
这似乎是最简单、最可靠和最快的解决方案。我不需要删除元素,所以跳过最后一行,但这不会增加任何开销。注意:我是在试图找到一个比$.ready js更快的替代noscript 标签时发现的。为了按我想要的方式使用它,我必须用一个1ms的setTimeout 函数来包装它。这立刻解决了我所有的问题。格雷西亚。
document.outerhtml="似乎做到了。
请记住,outerHTML 仍然是对标准的一个新的(ER)补充。如果您在编写时正在寻找对任何>6的软件的支持,则需要另一个解决方案。其他人提到的remove 函数也是类似的情况。像往常一样,使用polyfill是安全的。
您意识到这是Internet上唯一一个可以用这种方式删除DOM元素的地方。其他每个示例都使用removechild。干得好!!!!!!!
delete element 什么也不做,因为你不能删除JS中的变量,只能删除键;)你自己检查一下,在delete element 之后,console.log(element) 不起作用。
您可以创建一个remove 函数,这样您就不必每次都考虑它:
1 2 3 4
function removeElement( id) {
var elem = document.getElementById ( id) ;
return elem.parentNode .removeChild ( elem) ;
}
任何读过这篇文章的人都可能会认为"哇,聪明的一行程序",但事实上,它起作用是因为它分配给了全局变量elem 。如果你把它改成(var elem = ... ,它马上就不起作用了。另一个选择是(function(x){x.parentNode.removeChild(x);})(document.getElementById(id)) ,尽管我个人认为这不是"一条线"的收获。
如果你想在不全球化的情况下拥有一条航线,你可以将elem 改为remove.elem 。这样函数就引用了自身,所以不必创建另一个全局变量。-)
那么,你为什么要归还电子琴?为什么不是function remove(id) { document.getElementById(id).parentNote.removeChild(document.getElementById(id)); } 。
@扎克:虽然您的解决方案看起来更明显,但它执行两个较慢的DOM查找,其他解决方案似乎希望避免这种情况。
只需编写element.remove();现在就可以为我工作了!!
@扎克,应该是……埃多克斯1〔7〕…
不工作。错误太多。这项工作:var elem=document.getElementByID('id');elem.parentNode.removeChild(elem);
哇,为什么这么复杂。只需将元素本身传递给函数,而不是ID字符串。这样就可以在整个函数中访问元素,并且它保持一个线性。
@davidfari&241;whale,如果您想用这种方法删除一个元素,那么您将维护对已删除的dom元素的引用。我不太确定在有自己作用域的for循环中这会是什么样子,但我认为您的方法可能会导致内存泄漏(因为您可能在维护对已删除元素的引用,所以不会对它们进行垃圾收集)。我对此不是百分之百的肯定。虽然您的方法是好的,只要您知道您不需要在一个全局或大范围或跨函数中维护引用,它可能会变得混乱。
@Dylnmc说得对!我没想到这个。但是,只需将保存(不再存在)元素的变量设置为空,就可以避免这种情况。
简单而优雅!!谢谢。
这是DOM所支持的。在该页面中搜索"删除"或"删除",并且removechild是唯一删除节点的页面。
这回答了我最初的问题,但为什么JavaScript会这样工作?
我只是在猜测,但我认为这与内存管理有关。父节点很可能包含指向子节点的指针列表。如果您刚刚删除了一个节点(不使用父节点),那么父节点仍然会持有指针并导致内存泄漏。因此,API强制您对父级调用一个函数来删除子级。这也很好,因为它可以通过调用每个子节点上的remove来遍历树,并且不会泄漏内存。
嘿,伙计们,即使那个参考资料没有这个,我还是意外地发现了。写element.remove(); 就行了。也许是新的东西。但对我来说,这是第一次,而且效果很好。我认为它应该一直有效,因为它非常基本,必须有东西。
但在IE7及以下版本中不起作用。从IE7及以下版本中,remove()不起作用
如果我不得不猜测的话,它的工作原理是DOM元素不能删除它们自己。你在把众所周知的地毯从它的脚下移开。你必须把它从容器里拿出来。至少我是这么想的。
在DOM树中的节点A学院的定制,在每个节点有一个值的列表,以及一个引用它的子节点。因此element.parentNode.removeChild(element) mimics到底发生什么事:第一,你去漫游在父节点,然后删除参考节点的儿童。
作为辅助功能是提供一dom4,做同样的事情:element.remove() 。本厂在87 %的浏览器(如IE,但不是2016年)的11。如果你需要支持旧的浏览器,你可以:
通过删除元素的父节点,在这样的问题,
在本地修改DOM函数,如约翰德特马的回答,或
使用dom4 polyfill。
移除一个元件:
1 2
var elem = document.getElementById ( "yourid" ) ;
elem.parentElement .removeChild ( elem) ;
。
用于删除具有特定类名的所有元素:
1 2 3 4
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 方法返回的事实来保证的吗?
不幸的是,据我所知,它的存在并不能真正保证,但我不知道它的细节。我刚刚经历了一些奇怪的未定义或空值,我把检查放在那里,没有进一步调查。所以这有点像黑客。
应该是document.getElementsByClassName(... 。
实际上,应该是Elements 而不是Element 。谢谢您。
你只需使用element.remove() 。
element.remove() 不是有效的javascript,只能在某些浏览器(如chrome)中工作。
这在IE11中不起作用。
乔希,它是有效的javascript,除了火狐和Chrome实现了它(见MDN)
我的坏,element.remove() 是带有dom4的有效javascript,可以在所有现代浏览器中工作,当然除了Internet Explorer。
在火狐和Chrome上运行良好。谁在乎IE
有工作的人很关心IE!
根据mdn的childnode.remove()页面,edge也支持它。
一些有工作的人关心
MDN还为IE支持开发者提供了一个polyfill.mozilla.org/en-us/docs/web/api/childnode/&hellip;
的方法和ChildNode.remove() removes对象树是属于它的。
http://developer.mozilla.org /美国/文档/ / / / / childnode Web API
这里是一个你的小提琴表演呼叫document.getElementById('my-id').remove() CAN
http:/ / / / 52kp584l jsfiddle.net
* * * * * * * * * * * * * *
有没有需要的扩展列表。它已经已经实现。
* * * * * * * * * * * * * *
注意,这在任何版本的IE中都不受支持!
如果你还在发展,我很抱歉。
你不为IE发展吗?我为你的客户感到非常抱歉。
我也是。遗憾的是,我的事业也停留在过去。总有一天我们会一起摧毁互联网爆炸装置。
Having to go to the parent node first seems a bit odd to me, is there a reason JavaScript works like this?
该函数的名字是removeChild() ,和如何它可能解除儿童在没有父母吗?:)
在其他的手,你并不总是要调用它,你必须显示。element.parentNode 是只有一个助手把给定的父节点的节点。如果你已经知道父节点,你可以使用它像这样:
前:
1 2 3 4
// 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) ;
http://developer.mozilla.org /美国/文档/ /节点/网络/ API removechild
=========================================================
添加更多的东西:
有一些答案,而不是使用parentNode.removeChild(child); 角退出,你可以使用elem.remove(); 。但我已经注意到,有一个之间的差异的两个函数,它需要保持在这些答案。
如果你想使用removeChild() ,它返回一个从参考节点。
1 2
var removedChild = element.parentNode .removeChild ( element) ;
console.log ( removedChild) ; //will print the removed child.
但如果你使用elem.remove(); ,它不会返回你的参考。
1 2
var el = document.getElementById ( 'Example' ) ;
var removedChild = el.remove ( ) ; //undefined
http://developer.mozilla.org /美国/文档/ / / / / childnode Web API
这个行为可以观察和铬。我相信它的价值noticing:)
希望我的答案添加一些值的问题,将帮助!!
使用ele.parentnode.removechild(ele)的函数不能用于您已经创建但尚未插入到HTML中的元素。像jquery和prototype这样的库明智地使用如下方法来避免这种限制。
1 2 3 4 5
_limbo = document.createElement ( 'div' ) ;
function deleteElement( ele) {
_limbo.appendChild ( ele) ;
_limbo.removeChild ( ele) ;
}
号
我认为JavaScript的工作原理是这样的,因为DOM的原始设计人员将父/子和前/下一个导航作为比当前流行的DHTML修改更高的优先级。在90年代中期,能够从一个 中读取数据并通过DOM中的相对位置向另一个位置写入数据是很有用的,当时整个HTML表单或交互式GUI元素的动态生成在某些开发人员眼中几乎是一闪而过的。
根据DOM Level 4规格,这是目前的版本有一些新的发展,使用手机的方法:append() 突变,prepend() ,before() after() replace() remove() ,,,和。
http://red-team-design.com /删除到元与普通的JavaScript /删除方法
Having to go to the parent node first seems a bit odd to me, is there
a reason JavaScript works like this?
我的理由是:这是一样的我见过的其他环境:你是基于你的表演动作的"链接"到的东西。你不能删除它,你用它。
样切割树的肢体。坐在靠近侧closest while或树切割的结果将是……不幸的(非常有趣)。
这个来自火狐…有一次,Ie领先于包装,允许直接取出一个元件。
这只是我的假设,但我相信您必须通过父级移除子级的原因是因为Firefox处理引用的方式存在问题。
如果您调用一个对象来直接提交hari kari,那么在它死后,您仍然持有对它的引用。这有可能造成几个讨厌的虫子…例如,未能删除它、删除它但保持对它的引用看起来有效,或者只是内存泄漏。
我相信,当他们意识到这个问题时,解决方法是通过父元素删除一个元素,因为当该元素消失时,您现在只是持有对父元素的引用。这将停止所有的不愉快,并且(例如,如果一个节点一个节点地关闭一个树节点)将"压缩"得相当好。
这应该是一个很容易修复的bug,但是和Web编程中的其他许多事情一样,发布可能很匆忙,导致了这一点……当下一个版本出现时,有足够多的人在使用它,改变它将导致破坏一堆代码。
再说一次,所有这些只是我的猜测。
不过,我还是很期待有一天,Web编程终于得到了全面的春季大扫除,所有这些奇怪的小怪癖都被清理干净了,每个人都开始按照相同的规则玩起来。
可能是在我的机器人仆人起诉我要回工资的第二天。
我怀疑火狐对此负责。removeChild 是dom级别1 Node 接口的一种方法。
据我所知,直接删除节点在Firefox中不起作用,只有Internet Explorer。所以,为了支持火狐,你必须向父服务器请求删除它的子服务器。
参考:http://chiragrdarji.wordpress.com/2007/03/16/removedelete-element-from-page-using-javascript-working-in-firefox-ieopera/
这并不能真正回答我的问题,而且你链接到的页面提供了比我更糟糕的解决方案。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
// 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) ;
}
。
这是在不出现脚本错误的情况下删除元素的最佳函数:
1 2 3 4
function Remove( EId)
{
return ( EObj= document.getElementById ( EId) ) ? EObj.parentNode .removeChild ( EObj) : false ;
}
EObj=document.getElementById(EId) 注。
这是一个等号,不是== 。
如果元素EId 存在,那么函数将删除它,否则返回false,而不是error 。
创建全局变量。
这也是另一个答案的最糟糕版本,但晚了两年。