66

Is there a pure JavaScript function for inserting HTML before another element? In jQuery it can be accomplished like this:

$("#my_id").before('<span class="asterisk">*</span>');

If there isn't any equivalent JavaScript function how can I achieve the described functionality?

Robbendebiene
  • 4,215
  • 3
  • 28
  • 35
Aymand Osanes
  • 757
  • 1
  • 6
  • 9

4 Answers4

172

A little-known method is the element.insertAdjacentHTML. With this method (supported by all major browsers, including IE 4), you can take an arbitrary HTML string, and insert it anywhere in the document.

To illustrate the power of the method, let's use your example...:

$("#my_id").before('<span class="asterisk">*</span>');

Becomes

document.getElementById('my_id').insertAdjacentHTML('beforebegin',
    '<span class="asterisk">*</span>');

insertAdjacentHTML's first argument determines the insertion position. Here's a comparison with jQuery:

As you can see, it's very easy to use. Assuming that the jQuery selector returns only one element, you can in general use document.querySelector, but in this specific case, using document.getElementById is more efficient.

Rob W
  • 341,306
  • 83
  • 791
  • 678
  • 15
    @AymandOsanes Consider accepting this answer instead of the other. Most users know of standard DOM methods like `insertBefore` and `appendChild`, but `insertAdjacentHTML` is just sitting in a dusty corner. By accepting the answer, it gets bumped to the top and it'll be the first that users see when visiting this page. – Rob W Oct 11 '13 at 10:58
81

Edit: I prefer @Rob W's answer and think that that should be the accepted answer, not this one.


This will do what you want, without needing the support of any bloated libraries like jQuery.

var my_elem = document.getElementById('my_id');

var span = document.createElement('span');
    span.innerHTML = '*';
    span.className = 'asterisk';

my_elem.parentNode.insertBefore(span, my_elem);
Codemonkey
  • 4,455
  • 5
  • 44
  • 76
8

You can make your own function in javascript like,

Code

var id = document.getElementById('my_id');
var s = document.createElement('span');
s.innerHTML = '*';
s.className = 'asterisk';
id.parentNode.insertBefore(s, id);

InsertBefore Docs and Example

You can create a function before like,

before: function() {
    return this.domManip( arguments, false, function( elem ) {
        if ( this.parentNode ) {
            this.parentNode.insertBefore( elem, this );
        }
    });
},

source from http://code.jquery.com/jquery-1.9.1.js

Rohan Kumar
  • 40,431
  • 11
  • 76
  • 106
5

insertAdjacentElement

Sometimes, rather than an HTML string, you may have an element that you want to insert before another. An element instead might be useful if:

  • You want event listener(s) to be attached to children elements (and don't want to use inline handlers, because they're extremely poor practice). Or
  • You already have a reference to an element - perhaps one that already exists elsewhere on the page, or perhaps the element was created by some other function or script, and you want to inject it

In such situations, you can use .insertAdjacentElement. It's similar to .insertAdjacentHTML, except that it inserts an element at the desired position instead of inserting an HTML string at the desired position. You call it on the adjacent element, and to specify the position of the inserted element, for the first parameter, you may use 'beforebegin', 'afterbegin', 'beforeend', or 'afterend'.

Example:

const input = document.querySelector('input');
const addButton = document.querySelector('button');
const lastPost = document.querySelector('.posts div');

const createPost = (title) => {
  const newPost = document.createElement('div');
  newPost.appendChild(document.createElement('h4')).textContent = title;
  const button = newPost.appendChild(document.createElement('button'));
  button.textContent = 'Delete';
  button.addEventListener('click', () => newPost.remove());
  return newPost;
};
addButton.addEventListener('click', () => {
  const newPost = createPost(input.value);
  lastPost.insertAdjacentElement('beforebegin', newPost);
});
.posts div {
  padding: 10px;
  border: 1px solid black;
}
<input>
<button>Add post</button>

<h2>Posts</h2>
<div class="posts">
  <div>
    Last post
  </div>
</div>
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320