13

Consider following DOM fragment:

<div id="div-1">foo</div>
<div id="div-2">bar</div>

Is it possible to insert HTML string (EDIT: that contains tags to render) between divs without wrapping it in another div (EDIT: or some other tag) created via document.createElement and setting its innerHTML property?

4 Answers 4

20

Most browsers support element#insertAdjacentHTML(), which finally became standard in the HTML5 specification. Unfortunately, Firefox 7 and lower don't support it, but I managed to find a workaround that uses ranges to insert the HTML. I've adapted it below to work for your scenario:

var el = document.getElementById("div-2"),
    html = "<span>Some HTML <b>here</b></span>";

// Internet Explorer, Opera, Chrome, Firefox 8+ and Safari
if (el.insertAdjacentHTML)
    el.insertAdjacentHTML ("beforebegin", html);
else {
    var range = document.createRange();
    var frag = range.createContextualFragment(html);
    el.parentNode.insertBefore(frag, el);
}

Live example: http://jsfiddle.net/AndyE/jARTf/

Browser Support: https://caniuse.com/insertadjacenthtml

10

This does it for straight text, which is how I read your original question (see below for an update for strings that include tags):

var div = document.getElementById('div-2');
var textNode = document.createTextNode('your text');
div.parentNode.insertBefore(textNode, div);

Live example

If you start with:

<div id="div-1">foo</div>div id="div-2">bar</div>

(note that there's no whitespace between them) then the result of the above is exactly what you would get with this HTML:

<div id="div-1">foo</div>your text<div id="div-2">bar</div>

If you really have that whitespace between the divs, you'll already have a text node there and the above will insert another one next to it. For virtually all intents and purposes, that doesn't matter, but if that bothers you, you can append to the existing text node instead if you like:

var text = 'your text';
var div = document.getElementById('div-2');
var prev = div.previousSibling;
if (prev && prev.nodeType == 3) { // 3 == TEXT_NODE
  // Prev is a text node, append to it
  prev.nodeValue = prev.nodeValue + text;
}
else {
  // Prev isn't a text node, insert one
  var textNode = document.createTextNode(text);
  div.parentNode.insertBefore(textNode, div);
}

Live example

Links to W3C docs: insertBefore, createTextNode

Including HTML tags

In your revised question you've said you want to include tags to be interpreted in doing all this. It's possible, but it's roundabout. First you put the HTML string into an element, then you move the stuff over, like this:

var text, div, tempdiv, node, next, parent;

// The text
text = 'your text <em>with</em> <strong>tags</strong> in it';

// Get the element to insert in front of, and its parent
div = document.getElementById('div-2');
parent = div.parentNode;

// Create a temporary container and render the HTML to it
tempdiv = document.createElement('div');
tempdiv.innerHTML = text;

// Walk through the children of the container, moving them
// to the desired target. Note that we have to be sure to
// grab the node's next sibling *before* we move it, because
// these things are live and when we moev it, well, the next
// sibling will become div-2!
node = tempdiv.firstChild;
next = node.nextSibling;
while (node) {
  parent.insertBefore(node, div);
  node = next;
  next = node ? node.nextSibling : undefined;
}

Live example

But here there be dragons, you have to select the container element as appropriate to the content you're inserting. For instance, we couldn't use a <tr> in your text with the code above because we're inserting it into a div, not a tbody, and so that's invalid and the results are implementation-specific. These sorts of complexities are why we have libraries to help us out. You've asked for a raw DOM answer and that's what the above is, but I really would check out jQuery, Closure, Prototype, YUI, or any of several others. They'll smooth a lot of stuff over for you.

9
  • Maybe I do not understand you but this is exactly that I'm trying to avoid, wrapping HTML string into tag.
    – actual
    Commented Oct 26, 2010 at 11:43
  • "without wrapping it in another div created via document.createElement"
    – mplungjan
    Commented Oct 26, 2010 at 11:44
  • @actual: Fixed, sorry for misreading. It's exactly the same concept, it's just with a text node rather than an element. Commented Oct 26, 2010 at 11:46
  • Unfortunately, HTML tags are not working inside text node.
    – actual
    Commented Oct 26, 2010 at 11:52
  • @actual: No, they won't -- that's part of what a text node is for. I see you've edited your question. Okay, third edit coming, it is possible, it's just a pain. Commented Oct 26, 2010 at 12:04
0
var neuB = document.createElement("b");
var neuBText = document.createTextNode("mit fettem Text ");
neuB.appendChild(neuBText);
document.getElementById("derText").insertBefore(neuB, document.getElementById("derKursiveText"));

You search for: insertBefore

0

Using jquery it is very simple:

$("#div-1").after("Other tag here!!!");

See: jquery.after

It is obvious that javascript is not a pure javascript solution.

6
  • How that could be translated into pure JS + DOM?
    – actual
    Commented Oct 26, 2010 at 11:47
  • 1
    jQuery was written in javascript last time I looked :)
    – mplungjan
    Commented Oct 26, 2010 at 11:51
  • 1
    Well seeing most JS answers at SO involve jQuery, it is almost like jQuery==JavaScript ;) (but still not ===)
    – mplungjan
    Commented Oct 26, 2010 at 12:13
  • @mplungjan: It is, nevertheless, inappropriate and incorrect to answer a JavaScript / HTML / DOM question with a pure jQuery answer. (It's fine to give a pure JS answer and then say "but this would be easier if you used library X".) Commented Oct 26, 2010 at 12:38
  • true - I see a lot of answers on the net here and elsewhere that does not even bother to mention jQuery, just gives the jQuery example. Such is life ;)
    – mplungjan
    Commented Oct 26, 2010 at 13:52

Not the answer you're looking for? Browse other questions tagged or ask your own question.