94

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>

In jQuery, this would be very easy: $('.hi').remove();. I want to learn JS, and then jQuery.

I am stuck and Google has not provided. I do not want to become a copy/paste jQuery programmer. I am just starting to learn JS. Thanks.

leonheess
  • 16,068
  • 14
  • 77
  • 112
jonathanbell
  • 2,507
  • 5
  • 23
  • 40
  • 6
    Upvoted for wanting to learn JS before jQuery. And not wanting to just copy+paste. And for asking a good question. – Matt Feb 26 '16 at 21:54

4 Answers4

126

To remove an element you do this:

el.parentNode.removeChild(el);

MDN is a great reference. Here are a few relevant pages:

Node
parentNode
removeChild

However you'll run into issues if you loop like that since getElementsByClassName returns a live list, when you remove a node the element is removed from the list as well so you shouldn't increment or you will end up skipping every other element. Instead just continually remove the first element in the list, until there is no first element:

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

while(paras[0]) {
    paras[0].parentNode.removeChild(paras[0]);
}​

IMO jQuery is great at showing you what is possible to do in Javascript. I actually recommend that after about a week or two of plain JS you learn jQuery, get good at it, and remember what it's abstracting away. One day when you have an excellent grasp of Javascript scoping, objects, and such which you can obtain while using jQuery, go back and try learning how to interact better with the DOM without a library. That way you'll have an easier time learning plain JS and you'll appreciate the abstraction that libraries can provide you even more, while learning that when you only need one or two things a library provides you may be able to write them yourself without including the entire library.

Paul
  • 139,544
  • 27
  • 275
  • 264
  • Upvoted for the great jQuery analysis! Also applies to many frameworks, try substituting 'jQuery' for a different framework in the above text. – user2677034 Mar 08 '23 at 02:56
92

Simple ES6 answer:

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

Explanation:

  1. document.querySelectorAll() loops through the elements in the document returning a NodeList of all elements with the specified selector (e.g. '.class', '#id', 'button')
  2. forEach() loops through the NodeList and executes the specified action for each element
  3. e => e.remove() removes the element from the DOM
leonheess
  • 16,068
  • 14
  • 77
  • 112
  • 3
    Really like this one. And if you need IE support very badly you could make something like: `document.querySelectorAll('.classname').forEach(e => e.parentNode.removeChild(e));` to avoid polyfills, etc... – 40detectives May 17 '21 at 13:44
  • This is nice but if the element does not exist, it will error, no? const elems = document.querySelectorAll('classname'); while(elems[0]) { elems[0].remove(elems[0]); }​ – Yorick Mar 30 '23 at 14:40
  • @Yorick No, because querySelectorAll returns an empty NodeList if no element is found. Calling forEach on an empty Iterable will execute 0 times. – leonheess Mar 30 '23 at 18:07
19
[].forEach.call(document.querySelectorAll('.hi'),function(e){
  e.parentNode.removeChild(e);
});

Here I'm using Array.prototype.forEach to easily traverse all elements in an array-like object, i.e. the static NodeList returned by querySelectorAll, and then using removeChild() to remove the item from the DOM.

For older browsers that don't support querySelectorAll() or 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]);
  }
}

Note that because getElementsByTagName returns a live NodeList, you must iterate over the items from back to front while removing them from the DOM.

There are also some older browsers that don't support querySelectorAll but that do support getElementsByClassName, which you could use for increased performance and reduced code.

Phrogz
  • 296,393
  • 112
  • 651
  • 745
  • 1
    Don't call native methods on host objects without taking precautions, they are not required to be supported and aren't in some browsers. – RobG Jun 01 '12 at 00:29
  • @RobG Precautions like what? Condoms? :p It works in all modern browsers, and (for now) the _de facto_ standard behavior is likely to continue to be supported for backwards compatibility, putting up with fools like me who leaned on it once. – Phrogz Jun 01 '12 at 02:13
  • 2
    Unfortunately "modern" browsers are a subset of browsers in use. In most cases, "modern" is defined as "browsers that don't break when using my code". But IE 8 in quirks mode at least does not have qSA and even in standards mode will throw an error if host objects are passed to built-in methods. IE 8 is used by about 50% of IE users, so it may not be "modern", but it can't be ignored if you wish to write robust code for the general web. – RobG Jun 01 '12 at 03:05
  • @RobG Thank you for providing details. – Phrogz Jun 01 '12 at 03:26
1

Afaik only a parent can remove a child in native JS. So you would first have to get that elements parent, then use the parent to remove the element. Try this:

var parent = paras[i].parentNode;
parent.removeChild(paras[i]);
Matt Dodge
  • 10,833
  • 7
  • 38
  • 58