如何从DOM中删除所有特定类的元素?

95

var paras = document.getElementsByClassName('hi');

for (var i = 0; i < paras.length; i++) {
  paras[i].style.color = '#ff0011';
  // $('.hi').remove();
}
<p class="hi">dood</p>
<p class="hi">dood</p>
<p class="hi">dood</p>
<p class="hi">dood</p>
<p class="hi">dood</p>
<p>not class 'hi'</p>

在jQuery中,这很容易:$('.hi').remove();。我想先学习JS,然后再学习jQuery。
我陷入困境了,Google也没有提供帮助。我不想成为一个复制/粘贴的jQuery程序员。我刚开始学习JS。谢谢。

6
因为想先学习JS而对你点赞,也因为不想简单地复制粘贴,同时也提出了好问题。 - Matt
4个回答

128

要删除一个元素,您可以这样做:

el.parentNode.removeChild(el);

MDN是一个很好的参考。以下是一些相关页面:

Node
parentNode
removeChild

但是,如果像那样循环,你会遇到问题,因为getElementsByClassName返回的是动态列表。当你删除一个节点时,该元素也会从列表中删除,所以你不应该递增指针,否则你将会跳过每一个其他元素。相反,只需不断地移除列表中的第一个元素,直到没有第一个元素为止:

var paras = document.getElementsByClassName('hi');

while(paras[0]) {
    paras[0].parentNode.removeChild(paras[0]);
}​
在我看来,jQuery很擅长展示JavaScript的可行性。我建议你在学习了大约一两周纯JS后,学习使用jQuery,熟练掌握它并记住它所抽象出来的东西。等到你很好地掌握了JavaScript的作用域、对象等方面(你在使用jQuery时可以获得这些知识),再尝试着学习如何更好地与DOM交互而不需要使用库。这样,你会更轻松地学习纯JS,并且在学习时能够更加欣赏库所提供的抽象,同时也会明白当你只需要一个或两个库提供的功能时,你可能可以自己编写代码而无需引入整个库。

因为出色的jQuery分析而点赞!这也适用于许多框架,可以尝试在上面的文本中替换“jQuery”为其他框架。 - user2677034

95

简单的ES6答案:

document.querySelectorAll('.classname').forEach(e => e.remove());

解释:

  1. document.querySelectorAll() 循环遍历文档中的元素,返回具有指定选择器(例如 '.class''#id''button')的所有元素的 NodeList
  2. forEach() 循环遍历 NodeList,并对每个元素执行指定的操作
  3. e => e.remove() 从 DOM 中删除该元素

3
非常喜欢这个方法。如果你非常需要IE支持,你可以使用类似以下的代码: document.querySelectorAll('.classname').forEach(e => e.parentNode.removeChild(e)); 来避免使用polyfills等等。 - 40detectives
这很好,但如果元素不存在,它会出错,对吧?const elems = document.querySelectorAll('classname');while(elems[0]) { elems[0].remove(elems[0]); } - Yorick
@Yorick 不会,因为querySelectorAll如果没有找到元素,则返回一个空的NodeList。在空的可迭代对象上调用forEach将不执行任何操作。 - leonheess

19
[].forEach.call(document.querySelectorAll('.hi'),function(e){
  e.parentNode.removeChild(e);
});

在这里,我使用Array.prototype.forEach来方便地遍历类似数组的对象,即由querySelectorAll返回的静态NodeList,然后使用removeChild()从DOM中删除该项。

对于不支持querySelectorAll()forEach()的旧浏览器:

var classMatcher = /(?:^|\s)hi(?:\s|$)/;
var els = document.getElementsByTagName('*');
for (var i=els.length;i--;){
  if (classMatcher.test(els[i].className)){
    els[i].parentNode.removeChild(els[i]);
  }
}
请注意,由于getElementsByTagName返回的是一个实时的NodeList,您必须从后往前迭代每个项目并将其从DOM中删除。

还有一些较旧的浏览器不支持querySelectorAll,但它们支持getElementsByClassName,你可以使用它来提高性能和减少代码量。


1
不要在主机对象上调用本地方法而不采取预防措施,因为它们并非必须得到支持,并且在某些浏览器中也不受支持。 - RobG
@RobG 什么样的预防措施?避孕套?:p 它在所有现代浏览器中都可以使用,而且(目前)事实上的标准行为很可能会继续得到支持,以便向像我这样曾经依赖它的傻瓜们提供向后兼容性。 - Phrogz
2
不幸的是,“现代”浏览器只是使用中的浏览器的一个子集。在大多数情况下,“现代”被定义为“当使用我的代码时不会出错的浏览器”。但是,即使在标准模式下,IE 8也没有qSA,在怪异模式下甚至会在将宿主对象传递给内置方法时抛出错误。约有50%的IE用户使用IE 8,因此它可能不是“现代”的,但如果您希望为普通Web编写强大的代码,则不能忽略它。 - RobG
@RobG 感谢您提供的详细信息。 - Phrogz

1
据我所知,在本地JS中只有父级才能移除子级。因此,您首先需要获取该元素的父级,然后使用父级来移除该元素。请尝试以下操作:
var parent = paras[i].parentNode;
parent.removeChild(paras[i]);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接