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

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

问题描述

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

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>

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

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();
}

但我收到 Uncaught TypeError: Cannot read property 'remove' of undefined 错误.我觉得这很奇怪,但我想我会尝试添加一个守卫,看看会发生什么:

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.

问题演示

推荐答案

问题在于paragraphs 是一个活动列表.通过删除 p 元素,您也在更改该列表.一个简单的解决方法是以逆序遍历列表:

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 - 1; i >= 0; --i) {
  paragraphs[i].remove();
}

另一种解决方案是创建一个静态列表(非活动列表).您可以通过以下任一方式执行此操作:

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

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

  • 使用 document.querySelectorAll:

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

  • 然后您可以按常规顺序遍历列表(使用 for 循环):

    You can then iterate over the list in regular order (using a for loop):

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

    或(使用 for...of 循环):

    or (using a for...of loop):

    for (var paragraph of paragraphs) {
      paragraph.remove();
    }
    

    请注意,.remove 是一种相对较新的 DOM 方法,并非所有浏览器都支持.有关详细信息,请参阅 MDN 文档.

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

    为了说明问题,假设我们有一个包含三个元素的节点列表,paragraphs = [p0, p1, p2].那么当你遍历列表时会发生这种情况:

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

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

    所以在这个例子中,p1没有被删除,因为它被跳过了.

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

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

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