Sunday, October 28, 2007

The missing JavaScript insertAfter() function

I really have no idea why the XML/HTML DOM lacks an insertAfter() function. It seems like a pretty common operation. Thankfully, the solution is simple. So, for those who are learning JavaScript and/or the DOM (and for those of us who are too lazy or tired to think), here's what we need to do, in effect:

function insertAfter(new_node, existing_node) {
  // if the existing node has a following sibling, insert the current
  // node before it. otherwise appending it to the parent node
  // will correctly place it just after the existing node.

  if (existing_node.nextSibling) {
    // there is a next sibling. insert before it using the mutual
    // parent's insertBefore() method.
    existing_node.parentNode.insertBefore(new_node, existing_node.nextSibling);
  } else {
    // there is no next sibling. append to the end of the parent's
    // node list.
    existing_node.parentNode.appendChild(new_node);
  }
} // insertAfter()


The function checks the existing node for a next sibling. If it has one, inserting after the current nodei is the same as inserting before the next.  If it doesn't have a next sibling, it assumes that the existing node is the last node under the parent. So, it may append the new node right under the parent.

Simple.

That should do it. Let me know if you have any problems with it.


ADDENDUM: As one commenter pointed out, insertBefore() should actually perform the correct appendChild() operation if existing_node.nextSibling is null. The function above makes this very explicit, which I tend to like. But, we can also simplify it, almost to the point of absurdity:

function insertAfter(new_node, existing_node) {
  existing_node.parentNode.insertBefore(new_node, existingNode.nextSibling || null);
} // insertAfter()


17 comments:

  1. Hi, your code has helped me. :) Many thanks, willowdan

    ReplyDelete
  2. Worked perfectly, thanks!

    ReplyDelete
    Replies
    1. HTML5 Training in Chennai HTML5 Training in Chennai JQuery Training in Chennai JQuery Training in Chennai JavaScript Training in Chennai JavaScript Training in Chennai Full Stack Developer Training in Chennai Full Stack Developer Training in Chennai


      AngularJS Training in Chennai AngularJS Training in Chennai Node.js Training in CHennai Angular 2 Training in Chennai Angular 2 Training in Chennai Node.js Training in CHennai Node.js Training in chennai MEAN Developer Training in Chennai

      Delete
  3. Excellent snippet. Thank you!

    ReplyDelete
  4. Thanks Jon - this is very helpful. I am not infatuated with you btw, but I like your sweet Javascript skillz.

    ReplyDelete
  5. Hi

    The test on existing_node.nextSibling is useless since insertBefore will have the right behaviour if existing_node.nextSibling is null (cf https://developer.mozilla.org/en/DOM/element.insertBefore).

    ReplyDelete
  6. You are correct, sir. I'm not entirely sure why I put an explicit test on nextSibling in this function at the time of this post.

    In any case, you can certainly omit the test on nextSibling unless you want some kind of special functionality in the case that the element is the last in the parent node.

    ReplyDelete
  7. Thanks! Very useful.

    ReplyDelete
  8. Hello everybody! can someone give me an exemple of use to this code, I'm trying it but it doesn't work, thanks

    ReplyDelete
  9. Thanks! Very useful.

    ReplyDelete
  10. Additionally, for certain elements you can pass in the value “-1″ before appending.
    For example:
    var row = table.insertRow(-1);
    for (var c= 0; c < 4; c++)
    {
    var cell = row.insertCell(-1);
    cell.appendChild(document.createTextNode(data[i++]));
    }

    ReplyDelete
  11. Very Elegant. Thanks.

    ReplyDelete
  12. This is my first visit to your blog, your post made productive reading, thank you. dot net training in chennai

    ReplyDelete
  13. Informative article, just what I was looking for.seo services chennai

    ReplyDelete