There's insertBefore()
in JavaScript, but how can I insert an element after another element without using jQuery or another library?
19 Answers
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
Where referenceNode
is the node you want to put newNode
after. If referenceNode
is the last child within its parent element, that's fine, because referenceNode.nextSibling
will be null
and insertBefore
handles that case by adding to the end of the list.
So:
function insertAfter(newNode, referenceNode) {
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
}
You can test it using the following snippet:
function insertAfter(referenceNode, newNode) {
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
}
var el = document.createElement("span");
el.innerHTML = "test";
var div = document.getElementById("foo");
insertAfter(div, el);
<div id="foo">Hello</div>
Straightforward JavaScript Would Be the Following:
Append Before:
element.parentNode.insertBefore(newElement, element);
Append After:
element.parentNode.insertBefore(newElement, element.nextSibling);
But, Toss Some Prototypes In There For Ease of Use
By building the following prototypes, you will be able to call these function directly from newly created elements.
newElement.appendBefore(element);
newElement.appendAfter(element);
.appendBefore(element) Prototype
Element.prototype.appendBefore = function (element) {
element.parentNode.insertBefore(this, element);
},false;
.appendAfter(element) Prototype
Element.prototype.appendAfter = function (element) {
element.parentNode.insertBefore(this, element.nextSibling);
},false;
And, To See It All In Action, Run the Following Code Snippet
/* Adds Element BEFORE NeighborElement */
Element.prototype.appendBefore = function(element) {
element.parentNode.insertBefore(this, element);
}, false;
/* Adds Element AFTER NeighborElement */
Element.prototype.appendAfter = function(element) {
element.parentNode.insertBefore(this, element.nextSibling);
}, false;
/* Typical Creation and Setup A New Orphaned Element Object */
var NewElement = document.createElement('div');
NewElement.innerHTML = 'New Element';
NewElement.id = 'NewElement';
/* Add NewElement BEFORE -OR- AFTER Using the Aforementioned Prototypes */
NewElement.appendAfter(document.getElementById('Neighbor2'));
div {
text-align: center;
}
#Neighborhood {
color: brown;
}
#NewElement {
color: green;
}
<div id="Neighborhood">
<div id="Neighbor1">Neighbor 1</div>
<div id="Neighbor2">Neighbor 2</div>
<div id="Neighbor3">Neighbor 3</div>
</div>
insertAdjacentHTML
+ outerHTML
elementBefore.insertAdjacentHTML('afterEnd', elementAfter.outerHTML)
Upsides:
- DRYer: you don't have to store the before node in a variable and use it twice. If you rename the variable, on less occurrence to modify.
- golfs better than the
insertBefore
(break even if the existing node variable name is 3 chars long)
Downsides:
- lower browser support since newer: https://caniuse.com/#feat=insert-adjacent
- will lose properties of the element such as events because
outerHTML
converts the element to a string. We need it becauseinsertAdjacentHTML
adds content from strings rather than elements.
Though insertBefore() is great and referenced by most answers here. For added flexibility, and to be a little more explicit, you can use:
The insertAdjacentElement() as refElem.insertAdjacentElement(position, newElem)
lets you reference any element, and insert the to-be moved element exactly where you want (position can be one of: 'beforebegin'
, 'afterbegin'
, 'beforeend'
, 'afterend'
) as shown below:
// refElem.insertAdjacentElement('beforebegin', myElem);
<p id="refElem">
// refElem.insertAdjacentElement('afterbegin', myElem);
... content ...
// refElem.insertAdjacentElement('beforeend', myElem);
</p>
// refElem.insertAdjacentElement('afterend', myElem);
Others to consider for similar use cases: insertAdjacentHTML()
and insertAdjacentText()
References:
https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentElement https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentText
A quick Google search reveals this script
// create function, it expects 2 values.
function insertAfter(newElement,targetElement) {
// target is what you want it to go after. Look for this elements parent.
var parent = targetElement.parentNode;
// if the parents lastchild is the targetElement...
if (parent.lastChild == targetElement) {
// add the newElement after the target element.
parent.appendChild(newElement);
} else {
// else the target has siblings, insert the new element between the target and it's next sibling.
parent.insertBefore(newElement, targetElement.nextSibling);
}
}
2018 Solution (Bad Practice, go to 2020)
I know this question is Ancient, but for any future users, heres a modified prototype. This is just a polyfill for the .insertAfter function that doesnt exist. This prototype directly adds the function HTMLElement.insertAfter(element);
to the HTMLElement Prototype:
// Parent
const el = document.body;
// New Element
const newEl = document.createElement("div");
// Custom Method
Element.prototype.insertAfter = function(new) {
this.parentNode.insertBefore(new, this.nextSibling);
}
// Insert Before Element
el.insertBefore(newEl)
// Insert After Element
el.insertAfter(newEl);
// Just remember you cant use .insertAfter() or .insertBefore()
// after either is already called.
// You cant place one element in two places at once.
2019 Solution (Ugly / Outdated, go to 2020)
Don't use prototypes (Like the 2018 Solution). Overwriting the prototype is both dangerous, and low quality. If you want a new method, use Function Overrides Instead.
If you want a safe function for commercial projects, just use a default function. its not as pretty but it works:
// Parent
const el = document.body;
// New Element
const newEl = document.createElement("div");
// Function You Need
function insertAfter(el0, el1) {
el0.parentNode.insertBefore(el1, el0.nextSibling);
}
// Insert Before Element
el.insertBefore(newEl);
// Insert After Element
insertAfter(el, newEl);
// Just remember you cant use insertAfter() or .insertBefore()
// after either is already called.
// You cant place one element in two places at once.
2020 Solution - ChildNode
Current Web Standards for ChildNode: MDN Docs - ChildNode
Its currently in the Living Standards and is safe to use.
For unsupported browsers (Such as IE), use this Polyfill: https://github.com/seznam/JAK/blob/master/lib/polyfills/childNode.js
I realize the polyfill uses Proto Overrides, when I said they were bad practice. They are, especially when they are used blindly, like with my first solution. However, the polyfill on the MDN Documentation uses a form of initialization and execution that is much more reliable and safe compared to just overwriting a prototype.
How to use ChildNode:
// Parent
const el = document.body;
// New Element
const newEl = document.createElement("div");
// Insert Before Element
el.before(newEl);
// Insert After Element
el.after(newEl);
// Just remember you cant use .after() or .before()
// after either is already called.
// You cant place one element in two places at once.
// Another feature of ChildNode is the .remove() method,
// which deletes the element from the DOM
el.remove();
newEl.remove();
The method node.after
(doc) inserts a node after another node.
For two DOM nodes node1
and node2
,
node1.after(node2)
inserts node2
after node1
.
This method is not available in older browsers, so usually a polyfill is needed.
insertBefore() method is used like parentNode.insertBefore()
.
So to imitate this and make a method parentNode.insertAfter()
we can write the following code.
JavaScript
Node.prototype.insertAfter = function(newNode, referenceNode) {
return referenceNode.parentNode.insertBefore(
newNode, referenceNode.nextSibling); // based on karim79's solution
};
// getting required handles
var refElem = document.getElementById("pTwo");
var parent = refElem.parentNode;
// creating <p>paragraph three</p>
var txt = document.createTextNode("paragraph three");
var paragraph = document.createElement("p");
paragraph.appendChild(txt);
// now we can call it the same way as insertBefore()
parent.insertAfter(paragraph, refElem);
HTML
<div id="divOne">
<p id="pOne">paragraph one</p>
<p id="pTwo">paragraph two</p>
</div>
Note, that extending the DOM might not be the right solution for You as stated in this article.
Hovewer, this article was written in 2010 and things might be different now. So decide on Your own.
This is the simplest way we can add an element after another one using vanilla javascript
var d1 = document.getElementById('one');
d1.insertAdjacentHTML('afterend', '<div id="two">two</div>');
Reference: https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML
Ideally insertAfter
should work similar to insertBefore. The code below will perform the following:
- If there are no children, the new
Node
is appended - If there is no reference
Node
, the newNode
is appended - If there is no
Node
after the referenceNode
, the newNode
is appended - If there the reference
Node
has a sibling after, then the newNode
is inserted before that sibling - Returns the new
Node
Extending Node
Node.prototype.insertAfter = function(node, referenceNode) {
if (node)
this.insertBefore(node, referenceNode && referenceNode.nextSibling);
return node;
};
One common example
node.parentNode.insertAfter(newNode, node);
See the code running
// First extend
Node.prototype.insertAfter = function(node, referenceNode) {
if (node)
this.insertBefore(node, referenceNode && referenceNode.nextSibling);
return node;
};
var referenceNode,
newNode;
newNode = document.createElement('li')
newNode.innerText = 'First new item';
newNode.style.color = '#FF0000';
document.getElementById('no-children').insertAfter(newNode);
newNode = document.createElement('li');
newNode.innerText = 'Second new item';
newNode.style.color = '#FF0000';
document.getElementById('no-reference-node').insertAfter(newNode);
referenceNode = document.getElementById('no-sibling-after');
newNode = document.createElement('li');
newNode.innerText = 'Third new item';
newNode.style.color = '#FF0000';
referenceNode.parentNode.insertAfter(newNode, referenceNode);
referenceNode = document.getElementById('sibling-after');
newNode = document.createElement('li');
newNode.innerText = 'Fourth new item';
newNode.style.color = '#FF0000';
referenceNode.parentNode.insertAfter(newNode, referenceNode);
<h5>No children</h5>
<ul id="no-children"></ul>
<h5>No reference node</h5>
<ul id="no-reference-node">
<li>First item</li>
</ul>
<h5>No sibling after</h5>
<ul>
<li id="no-sibling-after">First item</li>
</ul>
<h5>Sibling after</h5>
<ul>
<li id="sibling-after">First item</li>
<li>Third item</li>
</ul>
I know this question has far too many answers already, but none of them met my exact requirements.
I wanted a function that has the exact opposite behavior of parentNode.insertBefore
- that is, it must accept a null referenceNode
(which the accepted answer does not) and where insertBefore
would insert at the end of the children this one must insert at the start, since otherwise there'd be no way to insert at the start location with this function at all; the same reason insertBefore
inserts at the end.
Since a null referenceNode
requires you to locate the parent, we need to know the parent - insertBefore
is a method of the parentNode
, so it has access to the parent that way; our function doesn't, so we'll need to pass the parent as a parameter.
The resulting function looks like this:
function insertAfter(parentNode, newNode, referenceNode) {
parentNode.insertBefore(
newNode,
referenceNode ? referenceNode.nextSibling : parentNode.firstChild
);
}
Or (if you must, I don't recommend it) you can of course enhance the Node
prototype:
if (! Node.prototype.insertAfter) {
Node.prototype.insertAfter = function(newNode, referenceNode) {
this.insertBefore(
newNode,
referenceNode ? referenceNode.nextSibling : this.firstChild
);
};
}
You can actually a method called after()
in newer version of Chrome, Firefox and Opera. The downside of this method is that Internet Explorer doesn't support it yet.
Example:
// You could create a simple node
var node = document.createElement('p')
// And then get the node where you want to append the created node after
var existingNode = document.getElementById('id_of_the_element')
// Finally you can append the created node to the exisitingNode
existingNode.after(node)
A simple HTML Code to test that is:
<!DOCTYPE html>
<html>
<body>
<p id='up'>Up</p>
<p id="down">Down</p>
<button id="switchBtn" onclick="switch_place()">Switch place</button>
<script>
function switch_place(){
var downElement = document.getElementById("down")
var upElement = document.getElementById("up")
downElement.after(upElement);
document.getElementById('switchBtn').innerHTML = "Switched!"
}
</script>
</body>
</html>
As expected, it moves the up element after the down element
This code is work to insert a link item right after the last existing child to inlining a small css file
var raf, cb=function(){
//create newnode
var link=document.createElement('link');
link.rel='stylesheet';link.type='text/css';link.href='css/style.css';
//insert after the lastnode
var nodes=document.getElementsByTagName('link'); //existing nodes
var lastnode=document.getElementsByTagName('link')[nodes.length-1];
lastnode.parentNode.insertBefore(link, lastnode.nextSibling);
};
//check before insert
try {
raf=requestAnimationFrame||
mozRequestAnimationFrame||
webkitRequestAnimationFrame||
msRequestAnimationFrame;
}
catch(err){
raf=false;
}
if (raf)raf(cb); else window.addEventListener('load',cb);
You can use appendChild
function to insert after an element.
Reference: http://www.w3schools.com/jsref/met_node_appendchild.asp
Lets handle all the scenarios
function insertAfter(newNode, referenceNode) {
if(referenceNode && referenceNode.nextSibling && referenceNode.nextSibling.nodeName == '#text')
referenceNode = referenceNode.nextSibling;
if(!referenceNode)
document.body.appendChild(newNode);
else if(!referenceNode.nextSibling)
document.body.appendChild(newNode);
else
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
}
a robust implementation of insertAfter.
// source: https://github.com/jserz/domPlus/blob/master/src/insertAfter()/insertAfter.js
Node.prototype.insertAfter = Node.prototype.insertAfter || function (newNode, referenceNode) {
function isNode(node) {
return node instanceof Node;
}
if(arguments.length < 2){
throw(new TypeError("Failed to execute 'insertAfter' on 'Node': 2 arguments required, but only "+ arguments.length +" present."));
}
if(isNode(newNode)){
if(referenceNode === null || referenceNode === undefined){
return this.insertBefore(newNode, referenceNode);
}
if(isNode(referenceNode)){
return this.insertBefore(newNode, referenceNode.nextSibling);
}
throw(new TypeError("Failed to execute 'insertAfter' on 'Node': parameter 2 is not of type 'Node'."));
}
throw(new TypeError("Failed to execute 'insertAfter' on 'Node': parameter 1 is not of type 'Node'."));
};