By Xah Lee


2011-01-25 12:39:36 8 Comments

There's insertBefore() in JavaScript, but how can I insert an element after another element without using jQuery or another library?

19 comments

@jszhou 2017-01-15 03:58:18

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'."));
};

@ρяσѕρєя K 2017-01-15 04:27:43

Add some explanation with answer for how this answer help OP in fixing current issue

@jszhou 2017-01-15 05:04:35

Run the code above,then you can insert a newNode after the specified referenceNode.

@Payel Dutta 2020-06-12 20:00:16

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

@Martin James 2020-08-04 17:12:32

Not really. This appends to the end or beginning, NOT after another element.

@Anime no Sekai 2020-05-26 17:20:28

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

@Mister SirCode 2019-12-16 16:34:41

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 micro polyfill for the .insertAfter function that doesnt exist this prototype directly adds a new function baseElement.insertAfter(element); to the Element prototype:

Element.prototype.insertAfter = function(new) {
    this.parentNode.insertBefore(new, this.nextSibling);
}

Once youve placed the polyfill in a library, gist, or just in your code (or anywhere else where it can be referenced) Just write document.getElementById('foo').insertAfter(document.createElement('bar'));


2019 Solution (Ugly, go to 2020)

New Edit: You SHOULD NOT USE PROTOTYPES. They overwrite the default codebase and arent very efficient or safe and can cause compatibility errors, but if its for non-commercial projects, it shouldnt matter. if you want a safe function for commercial use, just use a default function. its not pretty but it works:

function insertAfter(el, newEl) {
    el.parentNode.insertBefore(newEl, this.nextSibling);
}

// use

const el = document.body || document.querySelector("body");
// the || means "this OR that"

el.insertBefore(document.createElement("div"), el.nextSibling);
// Insert Before

insertAfter(el, document.createElement("div"));
// Insert After 


2020 Solution

Current Web Standards for ChildNode: https://developer.mozilla.org/en-US/docs/Web/API/ChildNode

Its currently in the Living Standards and is SAFE.

For Unsupported Browsers, use this Polyfill: https://github.com/seznam/JAK/blob/master/lib/polyfills/childNode.js

Someone mentioned that the Polyfill uses Protos, when I said they were bad practice. They are, especially when they are used incorrectly, like my solution for 2018. However, that polyfill is on the MDN Documentation and uses a kind of initialization and execution that is safer. Plus it IS for older browser support, in the day and age where Prototype Overwriting wasn't so bad.

How to use the 2020 Solution:

const el = document.querySelector(".class");

// Create New Element
const newEl = document.createElement("div");
newEl.id = "foo";

// Insert New Element BEFORE
el.before(newEl);

// Insert New Element AFTER
el.after(newEl);

// Remove Element
el.remove();

// Remove Child
newEl.remove(); // This one wasnt tested but should work

@karim79 2011-01-25 12:42:32

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>

@GijsjanB 2013-11-14 16:09:24

Thanks for a great answer, but isn't it confusing to flip referenceNode and newNode in the arguments list? Why not comply with the insertBefore syntax?

@Brad Vogel 2014-10-08 06:04:22

This code snippet doesn't handle if the referenceNode is the last child, in which it should appendChild.

@Pancho 2014-11-13 14:05:36

@BradVogel I think he explains that the case you mention is handled by insertBefore?

@electroCutie 2014-11-25 16:07:05

According to MDN if the element is last (and so nextSibling is null) the newNode will be appended as expected

@Bhumi Singhal 2016-08-08 07:30:28

referenceNode.nextElementSibling is a better option to be used

@7vujy0f0hy 2017-03-19 13:58:10

@BhumiSinghal: Wrong. insertBefore() works with text nodes. Why do you want insertAfter() to be different? You should create a separate pair of functions named insertBeforeElement() and insertAfterElement() for that.

@Donatas Navidonskis 2017-04-14 06:58:48

this function are great, but also and bad (not finished). reference node does not have any next siblings elements (example is the last child), function will not add the element, because reference does not have any more next siblings.

@do0g 2018-02-11 15:21:33

@DonatasNavidonskis: this concern has already been addressed by doublebackslash.

@mindplay.dk 2018-07-20 07:20:08

Unlike insertBefore, this function does not accept a null referenceNode - I went ahead and posted a function that does, and has the opposite behavior of insertBefore stackoverflow.com/a/51437118/283851

@Eugen Sunic 2018-10-09 14:28:47

The fiddle doesn't work for me, here is the stackblitz for the code instead stackblitz.com/edit/js-rshtm2?file=index.js

@Mukyuu 2019-03-27 08:08:34

Simply add random stuff to workaround "html is not defined" @DGRFDSGN e.g: const html='';

@flen 2020-03-16 23:40:08

This answer seems outdated, insertAdjacentElement looks like a better candidate nowadays. Could you maybe update your post to reflect this? This answer seems to be the most up-to-date: stackoverflow.com/a/50066247/4621141

@golopot 2016-10-27 07:55:24

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.

@Mister SirCode 2019-12-18 12:42:23

This takes a bit of manual work to implement as a functioning insertAfter though, so unfortunately I dont think this would work correctly.

@bit-less 2018-04-27 16:01:22

Though insertBefore() (see MDN) is great and referenced by most answers here. For added flexibility, and to be a little more explicit, you can use:

insertAdjacentElement() (see MDN) This lets you reference any element, and insert the to-be moved element exactly where you want:

<!-- refElem.insertAdjacentElement('beforebegin', moveMeElem); -->
<p id="refElem">
    <!-- refElem.insertAdjacentElement('afterbegin', moveMeElem); -->
    ... content ...
    <!-- refElem.insertAdjacentElement('beforeend', moveMeElem); -->
</p>
<!-- refElem.insertAdjacentElement('afterend', moveMeElem); -->

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

@serraosays 2019-10-28 20:45:19

Should really give this answer some love, it's the modern approach for the 2020s that are quickly approaching.

@Qwerty 2020-05-19 20:36:40

How come this answer is burried so deep? I shall reward it some points to bring more attention.

@mindplay.dk 2018-07-20 07:17:39

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

@yavuzkavus 2018-06-13 14:06:23

if( !Element.prototype.insertAfter ) {
    Element.prototype.insertAfter = function(item, reference) {
        if( reference.nextSibling )
            reference.parentNode.insertBefore(item, reference.nextSibling);
        else
            reference.parentNode.appendChild(item);
    };
}

@Ciro Santilli 郝海东冠状病六四事件法轮功 2014-05-11 05:56:20

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 because insertAdjacentHTML adds content from strings rather than elements.

@GetFree 2018-03-13 17:05:01

If you already have the element constructed, you can use .insertAdjacentElement()

@madannes 2018-05-30 14:26:29

As of 2018, browser support looks pretty solid: caniuse.com/#feat=insert-adjacent

@Mehregan Rahmani 2019-12-31 12:45:21

This was a nice solution, i suggest eveyone read this xahlee.info/js/js_insert_after.html

@Sami 2018-04-11 10:13:48

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

@Darlesson 2017-01-13 22:51:08

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 new Node is appended
  • If there is no Node after the reference Node, the new Node is appended
  • If there the reference Node has a sibling after, then the new Node 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>

@James Long 2011-01-25 12:43:00

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

@James Long 2013-11-11 11:40:27

For anyone who stumbles upon this script, I don't recommend using it. It attempts to solve problems that @karim79's native solution already solves. His script is faster and more efficient - I'd strongly recommend using that script instead of this one.

@dvdchr 2014-11-18 11:32:05

Why? It's just a couple more lines, with added conditional for last child edge case handling. Everything else is perfectly the same.

@James Long 2014-11-26 17:10:06

As a general-rule-of-thumb in JavaScript, the browser can do a task faster than anything you can write. Although the two solutions are functionally the same, my JavaScript solution needs to be read an understood by the browser before it can be used and requires an additional check each time it's executed. The solution offered by karim79 will do all this internally, saving those steps. The difference will be trivial at best, but his solution is the better one.

@1j01 2015-03-23 02:43:07

In other words, it's attempting to solve a problem that doesn't exist. There's nothing inherently wrong about the extra check, but I suppose it's not propagating the best understanding of these methods

@James Long 2015-03-23 11:58:16

Pretty much. I'm leaving the script here because it's the kind of thing I used to write, but the accepted answer is the better one, shows a better understanding of the methods and is faster. There's no reason use this answer instead - I'm not even sure why it still gets upvotes

@Rolf 2016-11-07 11:12:01

If targetElement is the last element amongst it's siblings, then targetElement.nextSibling will return null. When node.insertBefore is called with null as it's second argument, then it will add the node at the end of the collection. In other words the if(parent.lastchild == targetElement) { branch is superfluous, because parent.insertBefore(newElement, targetElement.nextSibling); will deal properly with all cases, even though it may appear otherwise at first. Many have already pointed that out in other comments.

@James Long 2016-11-08 09:18:53

@Rolf - yeah, that's why I don't recommend using this script and say it's better to use the accepted answer

@Doug LN 2016-12-14 12:12:37

You can use appendChild function to insert after an element.

Reference: http://www.w3schools.com/jsref/met_node_appendchild.asp

@Mehregan Rahmani 2019-12-31 12:03:24

This solution doesn't work for 2 p tags.. you cannot add a p tag after another p tag with this function ..

@Malik Khalil 2016-12-03 20:14:37

Step 1. Prepare Elements :

var element = document.getElementById('ElementToAppendAfter');
var newElement = document.createElement('div');
var elementParent = element.parentNode;

Step 2. Append after :

elementParent.insertBefore(newElement, element.nextSibling);

@olvlvl 2015-05-28 09:05:42

Or you can simply do:

referenceNode.parentNode.insertBefore( newNode, referenceNode )
referenceNode.parentNode.insertBefore( referenceNode, newNode )

@Ben J 2016-03-24 08:29:37

I wouldn't have thought of that approach. I'd prefer to use @karim79's more direct answer, but good to keep in mind.

@Armando 2015-08-21 08:05:13

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>

Run it on JSFiddle

@stomtech 2017-05-25 09:43:22

The extension function names are misleading. It think it should rather be called appendMeBefore and appendMeAfter. I thought it was used like the appendChild() Method, e.g. existingElement.appendAfter(newElement);. See what I mean at this updated jsfiddle.

@Stefan Steiger 2019-10-11 14:50:29

Append After works, because if element.nextSibling does not have a next sibling, nextSibling is NULL, and then it will append at the end.

@Chetabahana 2015-04-09 03:12:32

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

@Dmytro Dzyubak 2015-04-07 10:06:56

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.

JavaScript DOM insertAfter() method @ jsfiddle.net

Related Questions

Sponsored Content

73 Answered Questions

[SOLVED] How can I get query string values in JavaScript?

18 Answered Questions

[SOLVED] How to insert an item into an array at a specific index (JavaScript)?

61 Answered Questions

[SOLVED] How do I include a JavaScript file in another JavaScript file?

86 Answered Questions

[SOLVED] How do JavaScript closures work?

58 Answered Questions

[SOLVED] How do I redirect to another webpage?

3 Answered Questions

32 Answered Questions

[SOLVED] How can I change an element's class with JavaScript?

  • 2008-10-12 20:06:43
  • Nathan Smith
  • 2624464 View
  • 2815 Score
  • 32 Answer
  • Tags:   javascript html dom

57 Answered Questions

[SOLVED] How do I check if an element is hidden in jQuery?

41 Answered Questions

[SOLVED] How do I loop through or enumerate a JavaScript object?

39 Answered Questions

[SOLVED] How do you get a timestamp in JavaScript?

Sponsored Content