17

This is either very simple or impossible.

I know I can do this:

var element = document.getElementById('some_element');
element.parentNode.removeChild(element);

...but it feels messy. Is there a tidier - and universally supported - way to do the same thing?

It's seems - to me at least - like there should be something like this:

document.getElementById('some_element').remove();

...but that doesn't work, and searching Google/SO has not yielded any alternative.

I know it doesn't matter that much, but parentNode.removeChild() just feels hacky/messy/inefficient/bad practice-y.

DaveRandom
  • 87,921
  • 11
  • 154
  • 174

3 Answers3

35

It can seem a bit messy, but that is the standard way of removing an element from its parent. The DOM element itself can exist on its own, without a parentNode, so it makes sense that the removeChild method is on the parent.

IMO a generic .remove() method on the DOM node itself might be misleading, after all, we're not removing the element from existence, just from its parent.

You can always create your own wrappers for this functionality though. E.g.

function removeElement(element) {
    element && element.parentNode && element.parentNode.removeChild(element);
}

// Usage:
removeElement( document.getElementById('some_element') );

Or, use a DOM library like jQuery which provides a bunch of wrappers for you, e.g. in jQuery:

$('#some_element').remove();

This edit is in response to your comment, in which you inquired about the possibility to extend native DOM implementation. This is considered a bad practice, so what we do instead, is create our own wrappers to contain the elements and then we create whatever methods we want. E.g.

function CoolElement(element) {
    this.element = element;
}

CoolElement.prototype = {
    redify: function() {
        this.element.style.color = 'red';
    },
    remove: function() {
        if (this.element.parentNode) {
            this.element.parentNode.removeChild(this.element);
        }
    }
};

// Usage:

var myElement = new CoolElement( document.getElementById('some_element') );

myElement.redify();
myElement.remove();

This is, in essence, what jQuery does, although it's a little more advanced because it wraps collections of DOM nodes instead of just an individual element like above.

InteXX
  • 6,135
  • 6
  • 43
  • 80
James
  • 109,676
  • 31
  • 162
  • 175
  • +1, I like your remove element method, but it leads on to a sub question - is there any way to prototype methods for DOM elements (that works everywhere)? I have tried `HTMLElement.prototype` and the horrible-looking `Object.prototype` but neither work everywhere... – DaveRandom Sep 26 '11 at 21:11
  • 1
    Yes, there are ways to make it work, but it's considered a bad practice. That's why things like jQuery exist, to create an entirely separate object to contain elements, via which you can call methods. You can also extend jQuery. I'll add an EDIT to my answer. Gimme a sec :) – James Sep 26 '11 at 21:16
  • Agreed, setting aside my hatred of libraries like jQ (see comment on other answer) everything you say is true. – DaveRandom Sep 26 '11 at 21:19
  • Does this instruction `element && element.parentNode && element.parentNode.removeChild(element);` means that if the element exist and its' parent also exist, then remove the element? Why can we use multiple `&&` to do these steps? I don't know why can I do this. – Alston Jul 17 '15 at 06:53
  • @Stallman, for future reference, JS uses short circuit evaluation, which means that if `element` or `element.parentNode` do not exist, the logical operation will short circuit and return `false`. More info on this page: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators – John Harding May 09 '18 at 20:43
5

The DOM level 4 specs seems to have adopted the "jQuery philosophy" of doing several DOM changing operations (see https://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#interface-element). Remove is one of them:

var el = document.getElementById("myEl");
el.remove();

At this time, it's only supported in later version of Chrome, Opera, Firefox, but there are shims to patch this up if you want to use this functionality in production today: https://github.com/Raynos/DOM-shim

Wether it's preferable to removeChild or not, I leave undebated for now.

Daniel
  • 4,918
  • 4
  • 33
  • 34
1

Your code is the correct and best way to do it.

jQuery has what you're looking for:

$("#someId").remove();
SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • I thought that was probably the case but thought I'd ask in case there was something blindingly obvious that I had missed. I personally avoid JS frameworks because IMHO a) it is very rare it will save you any bandwidth in the long run - my pure-JS scripts tend to be smaller than library + my library-based code and b) it makes you lazy and you forget how the language actually works. I shall +1 anyway though, because you answer is definitely useful when I ignore my personal opinions... – DaveRandom Sep 26 '11 at 21:17
  • Frameworks let you forget how IE (mis-)works. Quick: How do you set `float` in Javascript using IE? – SLaks Sep 26 '11 at 21:23
  • Frameworks _encourage_ you to learn how Javascript works, while allowing you to forget how DOM works. They also allow you to develop _much_ faster. – SLaks Sep 26 '11 at 21:24
  • I do agree that it is nice to not have to worry about a cross-compat (and particularly IE cross-compat), but I don't see people encouraged to learn the nuts and bolts of the language - I work with many people who write jQ, not one of them has a clue where to start with Node, they seem to think some of the stuff I do is witchcraft... – DaveRandom Sep 26 '11 at 21:30
  • @Dave: That's their fault, and they will also have trouble with jQuery. Proper use of jQuery requires a deep understanding of raw Javascript, including closures, prototypes, and references. – SLaks Sep 26 '11 at 21:38
  • Do not refuse to use something because other people are stupid. (They use Javascript too, and you aren't refusing to use that) – SLaks Sep 26 '11 at 21:39
  • Well, I can't argue with that. But my other main concern is bandwidth - if there was a way to say to the browser "load the library once, at the beginning of the session, but keep your copy until I tell you otherwise" that worked *reliably* I would be much happier about it. But no matter what caching information I send, the user agent *may* choose to ignore it, and I don't like it. However, much as this is an intelligent conversation and you do have valid points to make, this is the kind of debate for which comments are not intended, so I am signing off here :-D – DaveRandom Sep 26 '11 at 21:49