1315

When removing an element with standard JavaScript, you must go to its parent first:

var element = document.getElementById("element-id");
element.parentNode.removeChild(element);

Having to go to the parent node first seems a bit odd to me, is there a reason JavaScript works like this?

Kamil Kiełczewski
  • 85,173
  • 29
  • 368
  • 345
Zaz
  • 46,476
  • 14
  • 84
  • 101
  • 580
    As James said, the DOM does not support removing an object directly. You have to go to its parent and remove it from there. Javascript won't let an element commit suicide, but it does permit infanticide... – Mark Henderson Aug 01 '10 at 23:36
  • 2
    So far I know, this is the only cross-browser way to remove child element if you use Javascript not any Javascript Library. – Nazmul Aug 02 '10 at 12:01
  • 22
    Is there a reason? [Richard Feynman says no](http://lesswrong.com/r/discussion/lw/99c/transcript_richard_feynman_on_why_questions/). (Well the technical justification is easy to see if you have written any tree-structure programs. The child must inform the parent _anyway_ otherwise the tree structure may be broken. Since it must do it internally anyway, if it provided you a one line function, it's just a convenient function for you that you may as well define yourself.) – kizzx2 Jan 09 '12 at 03:56
  • 6
    The only reason i see is that there should be always a root element in an xml/xhtml document, so you won't be able to remove it because it doesn't have a parent – Alex K Oct 16 '12 at 08:38
  • 5
    I quite like [Johan's workaround](http://stackoverflow.com/a/18120786), and I'm not sure why those functions aren't provided natively. As evidenced by the number of viewers, it's a very common operation. – Zaz Aug 12 '13 at 13:36
  • 1
    @kizzx2 Did you mean your link to go to "Feynman: F*****' magnets, how do they work?" Because, um, that's where it points, and I don't see anything in that transcript about DOM and element removal. (Okay, okay, I got what you meant, but magnetism is much less a human construct than JavaScript, I believe, making the OP's question here much more viable than that interviewer's. ;^D That said, admittedly, IANAP[hysicist].) – ruffin Dec 29 '15 at 19:51
  • @ruffin Well you kinda have the read the whole thing to get the point. But basically it's responding to the "seems a bit odd" part. Any "reason" would _also_ "seems a bit odd". Sometimes the world is just the way it is. And the actual "technical reason" is the tree-structure stuff but I reckon it wouldn't have been an intuitive answer as well so put that in parenthesis in a comment) – kizzx2 Dec 30 '15 at 05:29
  • IMHO: The reason for this is the same as I've seen in other environments: You are performing an action based on your "link" to something. You can't delete it while you're linked to it. Like cutting a tree limb. Sit on the side closest to the tree while cutting or the result will be ... unfortunate (although funny). – TheSatinKnight May 12 '17 at 03:28
  • 22
    You can use `element.remove()` directly as of ES5. You don't need the parent! – Gibolt Aug 13 '17 at 05:14
  • @MarkHenderson it's [prolicide](https://en.wikipedia.org/wiki/Prolicide), not infanticide, and as an _aside_, Javascript does allow [parricide](https://en.wikipedia.org/wiki/Parricide) via the grandparents. – Ronnie Royston Dec 16 '17 at 23:53
  • This works, once. I have a button that creates the element I want, then an evenListener that listens for click on another element, and triggers a function with this code (I also tried ````node.remove();````). With both snippets, it works the first time, but the second time I get the following error: ````Uncaught TypeError: Cannot read property 'remove' of null```` on the first line of the error, then ````at removeElement (script.js:23)```` on the second line of the error then ````at HTMLDivElement.document.getElementById.addEventListener (script.js:36)```` on the last line of the error. – Streching my competence Jan 22 '19 at 18:45
  • So the browser suddently returns "HTMLDivElement" (object) instead of "elemID" the second time around. Any idea what's happening? – Streching my competence Jan 22 '19 at 18:46

19 Answers19

757

I know that augmenting native DOM functions isn't always the best or most popular solution, but this works fine for modern browsers.

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

And then you can remove elements like this

document.getElementById("my-element").remove();

or

document.getElementsByClassName("my-elements").remove();

Note: this solution doesn't work for IE 7 and below. For more info about extending the DOM read this article.

EDIT: Reviewing my answer in 2019, node.remove() has come to the rescue and can be used as follows (without the polyfill above):

document.getElementById("my-element").remove();

or

[...document.getElementsByClassName("my-elements")].map(n => n && n.remove());

These functions are available in all modern browsers (not IE). Read more on MDN.

Johan Dettmar
  • 27,968
  • 5
  • 31
  • 28
  • 3
    Shouldn't it be [ document.getElementsByClassName("my-elements")[0].remove(); ] I think the function remove() ist not implemented by arrays. In order to remove all elements of a class or any selector returning an array, you have to iterate through all elements and call remove() on each. – Sedat Kilinc Dec 21 '14 at 17:17
  • 1
    @SedatKilinc, did you try the actual snippet? There are no arrays involved, but rather `NodeList` or `HTMLCollection` which are array-like set of elements. The second method definition allows for these "element sets" to be removed. – Johan Dettmar Jan 08 '15 at 15:48
  • 1
    Running this in the chrome console only seems to delete one element at a time when using `document.getElementsByClassName("my-elements").remove();`. Edit: actually it deletes a bunch but requires re-running to finish. Try it on this page with class "comment-copy". – DanielST Jul 07 '15 at 15:33
  • 2
    @slicedtoad you're right, my bad. I modified the function to loop backwards through the elements. Seems to work fine. The behavior you're talking about is most likely caused by updated indexes. – Johan Dettmar Jul 08 '15 at 14:07
  • @JohanDettmar ahh, that makes sense. – DanielST Jul 08 '15 at 15:48
  • what about `while(this.length){ this[0].parentElement.removeChild(this[0]); }` ? – Aureliano Far Suau Sep 02 '15 at 20:05
  • @AurelianoFarSuau, that should probably work as well (haven't tested it myself). However this loop will read the length value each time which might be slightly slower. Also to my knowledge you'd need `if(this[i] && this[i].parentElement)` to be sure that the current element still exists and has a parent element, otherwise you might get errors thrown for nested elements, etc. – Johan Dettmar Sep 28 '15 at 11:02
  • 1
    Don't do this. Simply remove items the way the language intends. Anyone familiar with parsing XML will recognize the need to get to the parent to delete children. HTML is a superset of XML (sort of). – Hal50000 Nov 02 '16 at 01:30
  • Especially useful when using a framework like DHTMLX suite, specifically when you have multiple forms in tabbars with the same name and id and you're trying to implement AJAX. Paste this at the top of each form to nullify previously loaded forms so that the current form is the only one that's loaded. Thanks a lot! – Wachaga Mwaura Dec 13 '17 at 06:30
  • Can you move your "update" to the top? Took a while to find it... – Nic Scozzaro Feb 25 '20 at 18:06
329

Crossbrowser and IE >= 11:

document.getElementById("element-id").outerHTML = "";
mb21
  • 34,845
  • 8
  • 116
  • 142
user2192293
  • 3,543
  • 1
  • 13
  • 9
  • 3
    This seems the simplest, most reliable, and fastest solution. I don't need to delete the element so I skip the last line, but that shouldn't add any overhead either way.. *Note*: I found this while trying to find a faster than `$.ready` js alternative to `noscript` tags. In order to use it how I wanted, I had to wrap it in a 1ms `setTimeout` function. This solves all of my problems at once. Gracias. – dgo May 01 '14 at 18:18
  • Keep in mind `outerHTML` is still a new(er) addition to to the standard. If you're looking for support on any software >6 at the time of writing, you'll need another solution. The `remove` function mentioned by others is a similar case. As usual it's safe to implement a polyfill. – Super Cat Aug 10 '16 at 21:31
  • `delete element` does nothing as you can't delete variables in JS, only keys ;) Check for yourself it doesn't work by `console.log(element)` after `delete element`... – Ivan Kleshnin Nov 23 '17 at 11:48
  • 2
    This is a bit slower than `removeChild` (about 6-7% on my system). See https://jsperf.com/clear-outerhtml-v-removechild/2 – Alejandro García Iglesias Jun 24 '19 at 05:58
  • 1
    This might leave a space where an iframe used to be if that's what you're trying to remove. – lacostenycoder Mar 13 '20 at 18:37
  • 1
    hey @dgo, you rock! – ChethiyaKD Jul 17 '21 at 20:22
195

You could make a remove function so that you wouldn't have to think about it every time:

function removeElement(id) {
    var elem = document.getElementById(id);
    return elem.parentNode.removeChild(elem);
}
Sarkar
  • 123
  • 1
  • 7
xsznix
  • 2,535
  • 2
  • 17
  • 14
  • 12
    If you want the one-liner without going global, you can change `elem` to `remove.elem`. That way the function references itself, so you don't have to create another global variable. :-) – twiz Dec 27 '12 at 05:35
  • 6
    so, why do you need to return the elem? Why not `function remove(id) { document.getElementById(id).parentNote.removeChild(document.getElementById(id)); }` – Zach Lysobey Apr 12 '13 at 17:00
  • 5
    @ZachL: Whilst your solution might seem the more obvious, it performs two DOM lookups which is slower and something the other solutions seem to want to avoid. – Wk_of_Angmar Jul 01 '13 at 23:39
  • 4
    Does not work. Too many errors. This works : var elem = document.getElementById('id') ; elem.parentNode.removeChild(elem); – Mitch Match Jan 22 '16 at 13:01
  • 2
    Wow, why so complicated. Just pass the element itself to the function instead of a id string. This way the element is accessible in the whole function plus it stays a one liner – David Fariña Sep 29 '16 at 08:52
  • 2
    @DavidFariña whale, if you wanted to remove an element with that approach, then you would maintain a reference to a deleted dom element. I am not quite certain what this would look like in a for loop that has its own scope, but I should think that your approach might lead to memory leaks (as you might be maintaining references to deleted elements, so they would not be garbage collected). I am not 100% certain of this. While your approach is fine as long as you understand that you need not maintain references in a global or large scope or cross-function, it can get messy. – dylnmc Jun 02 '17 at 18:35
  • @dylnmc good point! I didnt think of this. But this can be avoided by simply setting the variable that holds the (not anymore existing) element to null. – David Fariña Aug 10 '17 at 08:35
134

Update 2011

This was added to the DOM spec back in 2011, so you can just use:

element.remove()

The DOM is organized in a tree of nodes, where each node has a value, along with a list of references to its child nodes. So element.parentNode.removeChild(element) mimics exactly what is happening internally: First you go the parent node, then remove the reference to the child node.

As of DOM4, a helper function is provided to do the same thing: element.remove(). This works in 96% of browsers (as of 2020), but not IE 11.

If you need to support older browsers, you can:

KyleMit
  • 30,350
  • 66
  • 462
  • 664
Zaz
  • 46,476
  • 14
  • 84
  • 101
98

It's what the DOM supports. Search that page for "remove" or "delete" and removeChild is the only one that removes a node.

  • 14
    That answers my original question, but why does JavaScript work like this? – Zaz Aug 16 '10 at 18:18
  • 5
    I'm just guessing here, But I would assume it has to do with memory management. The parent node most likely holds a list of pointers to the child nodes. If you just deleted a node (without using parent), the parent would still hold the pointer and cause a memory leak. So the api forces you to call a function on the parent to delete the child. this also is nice because it can walk the tree down through the child nodes calling remove on each of them, and not leaking memory. – Chadams May 02 '13 at 16:22
  • 3
    hey guys, even though that reference doesn't have this, i found it accidentally. writing `element.remove();` will work. Maybe it's something new. But first time for me and it works. I think it should have worked always as it's very basic must have stuff. – Muhammad Umer Jul 09 '13 at 23:31
  • 1
    But it does not work in IE7 and below. From IE7 and below, remove() does not work – fanfan1609 Feb 13 '14 at 02:36
  • 1
    If I had to guess, the reason it works like this is that DOM elements can't remove themselves. You're removing the proverbial carpet from under it's feet. You have to remove it from the container. At least that's how I try to think of it. – PhilT Feb 17 '15 at 07:51
38

For removing one element:

 var elem = document.getElementById("yourid");
 elem.parentElement.removeChild(elem);

For removing all the elements with for example a certain class name:

 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]);
csjpeter
  • 1,721
  • 1
  • 14
  • 15
  • This is well covered by the existing answers. – KyleMit Aug 05 '14 at 13:24
  • 4
    +1 For simple example of removing by class name. This is not covered well by the other answers – Louise Eggleton Aug 14 '14 at 19:46
  • Why is the `if(list[i] && list[i].parentElement)` line necessary? Isn't the existence of each element guaranteed by the fact that it was returned by the `getElementsByClassName` method? – Hydrothermal Oct 21 '14 at 14:03
  • Unfortunately the existence is not really guaranteed as far as I know, but I do not know the details about it. I just experienced some strange undefined or null value once, and I put that check there without further investigation. So this is a bit of hack. – csjpeter Oct 22 '14 at 18:25
  • It should be `document.getElementsByClassName(...` – Worker Mar 19 '15 at 14:58
  • Really, it should be `Elements` instead of `Element`. Thank you. – csjpeter Mar 19 '15 at 15:13
27

you can just use element.remove()

Sai Sunder
  • 1,001
  • 1
  • 11
  • 16
  • 13
    `element.remove()` isn't valid JavaScript and only works in certain browsers such as [Chrome](http://stackoverflow.com/q/16151295). – Zaz Mar 01 '14 at 13:32
  • 4
    Josh, it is valid javascript, except only Firefox and Chrome implemented it (See MDN) – Tim Nguyen Jun 13 '14 at 08:04
  • 11
    My bad, [`element.remove()` *is* valid JavaScript with DOM4](http://dom.spec.whatwg.org/#childnode), and works in all modern browsers, naturally with the exception of Internet Explorer. – Zaz Jul 09 '14 at 19:07
  • 27
    Working fine on FireFox and Chrome. who cares about IE – Arun Sharma Oct 05 '14 at 06:29
  • 14
    people with jobs care about IE! – sqram Jun 01 '15 at 04:46
  • According to MDN's [ChildNode.remove()](https://developer.mozilla.org/en-US/docs/Web/API/ChildNode/remove) page, Edge supports it as well. – Rani Kheir May 28 '16 at 02:00
  • 2
    SOME people with jobs care about IE – Ascherer Feb 24 '17 at 21:27
  • 1
    MDN also provides a polyfill for IE support https://developer.mozilla.org/en-US/docs/Web/API/ChildNode/remove#Polyfill – aboutaaron Jul 24 '17 at 21:27
21

You can directly remove that element by using remove() method of DOM.

here's an example:

let subsWrapper = document.getElementById("element_id");
subsWrapper.remove();
//OR directly.
document.getElementById("element_id").remove();
Code Cooker
  • 881
  • 14
  • 19
20

The ChildNode.remove() method removes the object from the tree it belongs to.

https://developer.mozilla.org/en-US/docs/Web/API/ChildNode/remove

Here is a fiddle that shows how you can call document.getElementById('my-id').remove()

https://jsfiddle.net/52kp584L/

**

There is no need to extend NodeList. It has been implemented already.

**

Alex Fallenstedt
  • 2,040
  • 1
  • 18
  • 34
12

According to DOM level 4 specs, which is the current version in development, there are some new handy mutation methods available: append(), prepend(), before(), after(), replace(), and remove().

https://catalin.red/removing-an-element-with-plain-javascript-remove-method/

Red
  • 2,840
  • 1
  • 17
  • 11
9

You can simply use

document.getElementById("elementID").outerHTML="";

It works in all browsers, even on Internet Explorer.

David Buck
  • 3,752
  • 35
  • 31
  • 35
8

Having to go to the parent node first seems a bit odd to me, is there a reason JavaScript works like this?

The function name is removeChild(), and how is it possible to remove the child when there's no parent? :)

On the other hand, you do not always have to call it as you have shown. element.parentNode is only a helper to get the parent node of the given node. If you already know the parent node, you can just use it like this:

Ex:

// 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);

https://developer.mozilla.org/en-US/docs/Web/API/Node/removeChild

=========================================================

To add something more:

Some answers have pointed out that instead of using parentNode.removeChild(child);, you can use elem.remove();. But as I have noticed, there is a difference between the two functions, and it's not mentioned in those answers.

If you use removeChild(), it will return a reference to the removed node.

var removedChild = element.parentNode.removeChild(element); 
console.log(removedChild); //will print the removed child.

But if you use elem.remove();, it won't return you the reference.

var el = document.getElementById('Example');
var removedChild = el.remove(); //undefined

https://developer.mozilla.org/en-US/docs/Web/API/ChildNode/remove

This behavior can be observed in Chrome and FF. I believe It's worth noticing :)

Hope my answer adds some value to the question and will be helpful!!

Nimeshka Srimal
  • 8,012
  • 5
  • 42
  • 57
8

Functions that use ele.parentNode.removeChild(ele) won't work for elements you've created but not yet inserted into the HTML. Libraries like jQuery and Prototype wisely use a method like the following to evade that limitation.

_limbo = document.createElement('div');
function deleteElement(ele){
    _limbo.appendChild(ele);
    _limbo.removeChild(ele);
}

I think JavaScript works like that because the DOM's original designers held parent/child and previous/next navigation as a higher priority than the DHTML modifications that are so popular today. Being able to read from one <input type='text'> and write to another by relative location in the DOM was useful in the mid-90s, a time when the dynamic generation of entire HTML forms or interactive GUI elements was barely a twinkle in some developer's eye.

Alex
  • 1,457
  • 1
  • 13
  • 26
Psudo
  • 81
  • 1
  • 1
7

Shortest

I improve Sai Sunder answer because OP uses ID which allows to avoid getElementById:

elementId.remove();

box2.remove();          // remove BOX 2

this["box-3"].remove(); // remove BOX 3 (for Id with 'minus' character)
<div id="box1">My BOX 1</div>
<div id="box2">My BOX 2</div>
<div id="box-3">My BOX 3</div>
<div id="box4">My BOX 4</div>
Kamil Kiełczewski
  • 85,173
  • 29
  • 368
  • 345
3

Having to go to the parent node first seems a bit odd to me, is there a reason JavaScript works like this?

IMHO: The reason for this is the same as I've seen in other environments: You are performing an action based on your "link" to something. You can't delete it while you're linked to it.

Like cutting a tree limb. Sit on the side closest to the tree while cutting or the result will be ... unfortunate (although funny).

TheSatinKnight
  • 696
  • 7
  • 16
2

From what I understand, removing a node directly does not work in Firefox, only Internet Explorer. So, to support Firefox, you have to go up to the parent to remove it's child.

Ref: http://chiragrdarji.wordpress.com/2007/03/16/removedelete-element-from-page-using-javascript-working-in-firefoxieopera/

James
  • 196
  • 3
  • 7
    That doesn't really answer my question, and the page you linked to provides a worse solution than mine. – Zaz Aug 01 '10 at 22:02
2

This one actually comes from Firefox... for once, IE was ahead of the pack and allowed the removal of an element directly.

This is just my assumption, but I believe the reason that you must remove a child through the parent is due to an issue with the way Firefox handled the reference.

If you call an object to commit hari-kari directly, then immediately after it dies, you are still holding that reference to it. This has the potential to create several nasty bugs... such as failing to remove it, removing it but keeping references to it that appear valid, or simply a memory leak.

I believe that when they realized the issue, the workaround was to remove an element through its parent because when the element is gone, you are now simply holding a reference to the parent. This would stop all that unpleasantness, and (if closing down a tree node by node, for example) would 'zip-up' rather nicely.

It should be an easily fixable bug, but as with many other things in web programming, the release was probably rushed, leading to this... and by the time the next version came around, enough people were using it that changing this would lead to breaking a bunch of code.

Again, all of this is simply my guesswork.

I do, however, look forward to the day when web programming finally gets a full spring cleaning, all these strange little idiosyncracies get cleaned up, and everyone starts playing by the same rules.

Probably the day after my robot servant sues me for back wages.

Alex
  • 1,457
  • 1
  • 13
  • 26
  • 11
    I doubt that Firefox is responsible for this. `removeChild` is a method of the [DOM Level 1 `Node` interface](http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-core.html#ID-1950641247). – Felix Kling Aug 24 '11 at 00:46
1
// 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);
}
will Farrell
  • 1,733
  • 1
  • 16
  • 21
-2

This is the best function to remove an element without script error:

function Remove(EId)
{
    return(EObj=document.getElementById(EId))?EObj.parentNode.removeChild(EObj):false;
}

Note to EObj=document.getElementById(EId).

This is ONE equal sign not ==.

if element EId exists then the function removes it, otherwise it returns false, not error.

Wilk
  • 7,873
  • 9
  • 46
  • 70