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?
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.
Crossbrowser and IE >= 11:
document.getElementById("element-id").outerHTML = "";
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);
}
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:
Remove elements via the parent node
Modify the native DOM functions, as in Johan Dettmar's answer, or
Use a DOM4 polyfill.
It's what the DOM supports. Search that page for "remove" or "delete" and removeChild is the only one that removes a node.
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]);
you can just use element.remove()
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();
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.
**
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/
You can simply use
document.getElementById("elementID").outerHTML="";
It works in all browsers, even on Internet Explorer.
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!!
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.
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>
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).
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/
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.
// 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);
}
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.
How do I extract array data from the object <div class="gwt-Label">Some Data</div>?
Since #BrockAdams provided an excellent answer and solution for the general problem of data extraction from a DIV object, described by class name only (no id) and since the web page is made of 100+ DIV objects, described by the same class name, mainly "gwt-Label"
How do I extract the text from a (dynamic) div, by class name, using a userscript?
I am looking for a solution to limit the output to the console from 100+ lines to just few by modifying the code by #BrockAdams below
waitForKeyElements (".gwt-Label", printNodeText);
function printNodeText (jNode) {
console.log("gwt-Label value: ", jNode.text().trim());
}
Since the output I read in the console is 100+ lines long, but all I need is just a few selected lines by array index.
Do you know how to manipulate jNode to save output to an array first and have only the selected array elements to be reread and send to the console?
I would prefer pseudocode like this:
jNode.text().trim()[0]
jNode.text().trim()[5]
Run as a script in Greasemonkey or Tampermonkey.
And what's more, I need to loop the script over a numerical query string setting dynamic #match URL in the script.
Okay, if you have lots of class gwt-Label elements and, assuming that they are AJAX'd in in separate batches, you can put them into an array with code like this:
var valArry = [];
var ajxFinshTmr = 0;
waitForKeyElements (".gwt-Label", storeValue);
function storeValue (jNode) {
valArry.push (jNode.text ().trim () );
if (ajxFinshTmr) clearTimeout (ajxFinshTmr);
//-- Let all initial AJAX finish, so we know array is complete.
ajxFinshTmr = setTimeout (printFinalArray, 200);
}
function printFinalArray () {
console.log ("The final values are: ", valArry);
}
Note that there are almost certainly more robust/efficient/sensible alternatives, but we need to see more of the true page, and the true goal, to engineer those.
ETA: I see you've just linked to the site. Now describe in detail what you want to do. The possibilities can be quite messy.
it took me days to understand the problem
// ==UserScript==
// #name Important test1
// #namespace bbb
// #include http://srv1.yogh.io/#mine:height:0
// #version 1
// ==/UserScript==
console.log("sdfasg");
window.setTimeout(function() {
var HTMLCollection = document.getElementsByClassName("gwt-Label");
console.log(HTMLCollection);
var elements = HTMLCollection.length;
console.log(elements);
element = HTMLCollection[6];
console.log(element);
text = element.innerHTML;
console.log(text);
textclass= text.innerHTML;
// console.log(textclass);
console.log("15minutes");
}, 15000);
var HTMLCollection = document.getElementsByClassName();
console.log(HTMLCollection);
#BrockAdams was very helpful.
Since the above site loaded at random time duration so GM script one day worked fine, generating HTMLCollection in full but another time generated it empty, making innerHTML to generate undefined value.
Great success came with "353 moreā¦ ]" HTMLCollection link to Open In Variables View, generating exactly what I tried to accomplish via XPath, generating indexed (numered) list of all DIV objects in my HTMLCollection, to let me select DIV object of interest by known number.
I am still looking for alike solution provided by DOM Parsing and Serialization
[https://w3c.github.io/DOM-Parsing/#][1]
to work for me to append natural number, index to every DOM object of HTML document to let me use it in parallel with XPath generated by Firebug
example
html/body/div[3]/div[3]/div/div[6]/div[2]/div/div/div
followed by
html1/body2/div[3]5or-higher/div[3]/div/div[6]/div[2]/div/div/div
just serializing HTML DOM object, appending unique index to each object to let me call it via HTMLCollection[index] or better HTMLDOMCollection[index]
I am sure such approach has been known and adopted by HTML DOM serializer parser but I don't know how to access it.
thank you all
I'm writing a Chrome content script extension and I need to be able to target a specific element that, unfortunately, has no unique identifiers except its parent element.
I need to target the immediate first child element of parentElement. console.log(parentElement) reports both of the child elements/nodes perfectly, but the succeeding console logs (the ones that target the childNodes) always return an undefined value no matter what I do.
This is my code so far
(I have excluded the actual names to avoid confusion and extra, unnecessary explanation)
function injectCode() {
var parentElement = document.getElementsByClassName("uniqueClassName");
if (parentElement && parentElement.innerHTML != "") {
console.log(parentElement);
console.log(parentElement.firstElementChild);
console.log(parentElement.firstChild);
console.log(parentElement.childNodes);
console.log(parentElement.childNodes[0]);
console.log(parentElement.childNodes[1]);
} else {
setTimeout(injectCode, 250);
}
}
How do I select the first child element/node of parentElement?
Update:
parentElement.children[0] also has the same error as parentElement.childNodes[0].
Both these will give you the first child node:
console.log(parentElement.firstChild); // or
console.log(parentElement.childNodes[0]);
If you need the first child that is an element node then use:
console.log(parentElement.children[0]);
Edit
Ah, I see your problem now; parentElement is an array.
If you know that getElementsByClassName will only return one result, which it seems you do, you should use [0] to dearray (yes, I made that word up) the element:
var parentElement = document.getElementsByClassName("uniqueClassName")[0];
I am trying to convert my jQuery script into javascript. I have a problem there..
I have a script that creates a node
var new_node = document.createElement("div");
new_node.className="tooltip";
new_node.innerHTML = html;
alert(new_node.className);
When i do this
jQuery(link).after(new_node);
It works fine. But I want to do it javascript way. I have tried using appendChild function but it gives some strange results.
Please help me out with this.
You're comparing jQuery's after with appendChild, but they do very different things. after puts the element after the reference element, appendChild puts it inside it.
You probably want insertBefore (with the reference node being link's nextSibling).
So:
var link = /* ... get the `a` element from somewhere ... */;
var new_node = document.createElement("div");
new_node.className="tooltip";
new_node.innerHTML = html;
link.parentNode.insertBefore(new_node, link.nextSibling);
If link is the last thing in its parent, that's fine; link.nextSibling will be null and insertBefore accepts null as the reference node (it means "insert at the end").
Assuming you already have a node instantiated as link, you could do what you want this way in plain Javascript:
link.parentNode.appendChild(new_node);
The link node would have to be the last node in its container. Otherwise you would have to find link's nextSibling and use insertBefore to put new_node in its proper place.
jQuery(link).append(new_node);
I am traversing a HTML document using javascript DOM. I want make a list (an array actually) of all nodes/elements and their values. I found a script for traversing DOM, but how do I store each node value in an array. I can't seem to find the unique identifier for a node. Anyone has any pointers? I was thinking of xpath or something.
Is it a good idea to consider xpath for node as the unique identifier. If so how do I get xpath of a element while traversing the DOM?
As programmer born and brought up in the world of C and C++, my first answer to this kind of question would have been "store their addresses in the array!". But after a couple years of messing around with the web way of things, I can give the right answer:
In javascript, you can directly store the references to the objects in the array.
And no, xpath is not a good idea for this; using references is simpler and better.
So a direct answer to your question is: there is no unique identifier for a DOM element/node except itself.
In javascript, all objects are passed around by reference. So here's a sample code for how to do it:
var theArray = [];
var theNodeToTraverse = document.getElementById('domelementtosearch');
traverseAndStore(theNodeToTraverse);
function traverseAndStore( node )
{
if( node==null) return;
theArray[ theArray.length ] = node;
for( i=0; i<node.childNodes.length; i++ )
traverseAndStore( node.childNodes[i] );
}
You can get something similar to xpath with something like this. It traverses the dom upwards from the input element through the parentNode property.
https://gist.github.com/sebjwallace/3c0a6f7493ce23134516
It will output a string like this.
"#document/HTML/BODY/DIV"
var getElementPath = function(el){
var path = el.nodeName;
var parent = el.parentNode;
while(parent){
path = parent.nodeName + '/' + path;
parent = parent.parentNode;
}
return path;
}
EDIT:
The question seems to point to a simple flatmap solution. I think my original answer was aimed at generating an address for each node in the DOM. This solution almost as basic as flatmap. Well, the DOM is a tree with N children per node. Given a snapshot of the DOM you can generate an address of each element given the child index. As an example of stackoverflow's DOM, grabbing the one of the nodes 5 levels deep - the address is 01001. Each address will be unique for every element in the DOM. This won't work if you need a static address for a dynamic web app however.