从DOM中删除HTMLCollection元素 [英] Removing HTMLCollection elements from the DOM

查看:436
本文介绍了从DOM中删除HTMLCollection元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个段落元素的集合。有些是空的,有些只包含空格,而其他的则包含内容:

 &p> Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas。前庭弯曲曲棍球,发脾气,多余的eget,暂时坐在一起。 Donec eu libero sit amet quam egestas semper。 Aenean ultricies mi vitae est。Mauris placerat eleifend leo。< / p> 
< p>< / p>
< p> < / p为H.
< p> < / p为H.
< p>& nbsp;< / p>
< p> &安培; NBSP;< / p为H.

我正在使用 getElementsByTagName 来选择它们:

  var paragraph = document.getElementsByTagName('p'); 

这将返回文档中的所有段落。我想删除所有这些,所以我想为(var i = 0,len =段落)运行

 长度; i 段落[i] .remove(); 
}

但我得到未捕获TypeError:无法读取属性删除未定义的错误。我认为这很奇怪,但是我会尝试添加一个守卫,看看会发生什么:

  for(var i = 0 ,len = paragraphs.length; i< len; i ++){
paragraph [i]&&&段落[I]卸下摆臂();
}

没有错误,但并非所有元素都被删除。所以我再次运行它,它删除了以前没有删除的元素的一些。我再次运行 所有段落都从文档中删除。



我想知道什么明显的细节我在这里错过。



问题的演示

解决方案

问题是段落实时列表。通过删除 p 元素,您也正在更改该列表。一个简单的修复是以相反的顺序迭代列表:

  for(var i = paragraphs.length; i--; ){
段[i] .remove();
}

替代解决方案是创建非活动(静态)列表。您可以通过以下方式之一执行此操作:




  • 将列表转换为真实数组

      var paragraph = 
    Array.prototype.slice.call(document.getElementsByTagName('p'),0);


  • 使用 document.querySelectorAll ,它返回一个静态列表(不是活的!):

      var paragraph = document.querySelectorAll('p'); 




请注意。删除是一种相对较新的DOM方法,每个浏览器都不支持。请参阅 MDN文档 更多信息






为了说明问题,让我们想象一下,我们有一个三个元素的节点列表, paras = [p0,p1,p2] 。那么当你重复列表时,会发生什么:

  i = 0,length = 3,paras [0] == p0 => paras = [p1,p2] 
i = 1,length = 2,paras [1] == p2 => paras = [p1]
i = 2,length = 1,END

p1 未被删除,因为它被跳过。


I have a collection of paragraph elements. Some are empty and some contain whitespace only, while others have content:

<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>
<p></p>
<p> </p>
<p>    </p>
<p>&nbsp;</p>
<p> &nbsp;</p>

I'm using getElementsByTagName to select them:

var paragraphs = document.getElementsByTagName('p');

This returns all paragraphs in the document. I want to remove all of them, so I'd like to run

for (var i = 0, len = paragraphs.length; i < len; i++) {
   paragraphs[i].remove();
}

but I get Uncaught TypeError: Cannot read property 'remove' of undefined errors. I think this is strange, but figure I'll try adding a guard and see what happens:

for (var i = 0, len = paragraphs.length; i < len; i++) {
   paragraphs[i] && paragraphs[i].remove();
}

No error, but not all elements are removed. So I run it again, and it removes some of the elements which weren't removed previously. I run it again and finally all of the paragraphs are removed from the document.

I'm wondering what obvious detail I'm missing here.

Demo of the problem

解决方案

The problem is that paragraphs is a live list. By removing a p element you are also changing that list. A simple fix is to iterate over the list in reverse order:

for (var i = paragraphs.length; i--; ) {
   paragraphs[i].remove();
}

The alternative solution is to create a non-live (static) list. You can do this by either:

  • convert the list to a real array

    var paragraphs =
      Array.prototype.slice.call(document.getElementsByTagName('p'), 0);
    

  • use document.querySelectorAll, which returns a static list (not live!):

    var paragraphs = document.querySelectorAll('p');
    

Note that .remove is a relative new DOM method, and not supported in every browsers. See the MDN documentation for more info.


To illustrate the problem, lets imagine we have a node list of three elements, paras = [p0, p1, p2]. Then this is what happens when you iterate over the list:

i = 0, length = 3, paras[0] == p0  => paras = [p1, p2]
i = 1, length = 2, paras[1] == p2  => paras = [p1]
i = 2, length = 1, END

So in this example, p1 is not deleted because it is skipped.

这篇关于从DOM中删除HTMLCollection元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆