2

Is it possible to insert DOM HTML element at the point of execution of <script> tag? Like with document.write() function which immediately inserts text into DOM when executed.

[UPDATE]

Yes it is! Here's what I came up with:

var injectElement = function (element) {
    //Function that generates random id
    var randomID = function () {
        var id = '';
        var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
        for( var i=0; i < 5; i++ )
           id += chars.charAt(Math.floor(Math.random() * chars.length));
       return id;
    };

    var id = randomID();

    //Adding placeholder element
    document.write('<div id="' + id + '"></div>');

    //Injecting new element instead of placeholder
    var placeholder = document.getElementById(id)
    placeholder.parentNode.replaceChild(element, placeholder);
};
Jinx
  • 857
  • 2
  • 14
  • 28
  • 2
    Why what are you trying to achieve? Why not simple place a placeholder there (e.g. an empty DIV) and append elements there? – Yuriy Galanter Sep 20 '13 at 21:45
  • So you want to do the same as `document.write` does, but without `document.write`? – bfavaretto Sep 20 '13 at 21:46
  • @bfavaretto if I pass object to `document.write` it'll convert it to a string. I want to insert html element at the place of ` – Jinx Sep 20 '13 at 21:52
  • @YuriyGalanter i want to insert `canvas` element without having to reference id. You just place script in body of a document like this `` – Jinx Sep 20 '13 at 21:54
  • That really isn't how that's done. You need to put a place-holder element in the body, something you can find by ID, and then append a `` element to it with some script either running in the `` or in an external .js file. – user229044 Sep 20 '13 at 22:00
  • @meagar I know how it's usually done, but that wasn't the question. It occured to me that sometimes it would be much practical to do something like `document.write` but for HTML elements. And so far, no clear answer. Yes or No? – Jinx Sep 20 '13 at 22:03

3 Answers3

1

Yes this is possible:

<script>
    var arrScripts = document.getElementsByTagName('script');
    var currScript = arrScripts[arrScripts.length - 1];

    var newNode = document.createElement('div');
    newNode.innerHTML = 'This is a DIV';

    currScript.parentNode.appendChild(newNode);

</script>

This code first locates current script block within the document and then appends DOM element after it.

Yuriy Galanter
  • 38,833
  • 15
  • 69
  • 136
  • 2
    [This is not failproof](http://stackoverflow.com/questions/14409982/is-it-the-last-script-element-the-currently-running-script/14410368#14410368) – bfavaretto Sep 20 '13 at 22:04
  • A safer option is using ` – bfavaretto Sep 20 '13 at 22:07
  • @bfavaretto completely agree and this is what I was doing initially. But then OP stated he wanted to do this "*without having to reference id.*" – Yuriy Galanter Sep 20 '13 at 22:08
  • @bfavaretto yes, this was supposed to be my fallback. But this was interesting to know. – Jinx Sep 20 '13 at 22:09
  • 1
    There're other way to identify current script block (like placing a unique string within the block). Whatever works best. – Yuriy Galanter Sep 20 '13 at 22:10
0

Ok, so I gave this one a little bit of thought and I think I have created a fail safe way to inject element into DOM after the <script> tag with something as simple as:

<script>
    injectElement(document.createElement('canvas'));
</script>

First I use document.write to insert div with random id attribute. After that, I get that placeholder with random id and replace it with my new element that I want to inject.

Genius if I may say so my self :D

Here's the code:

var injectElement = function (element) {
    //Function that generates random id
    var randomID = function () {
        var id = '';
        var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
        for( var i=0; i < 5; i++ )
           id += chars.charAt(Math.floor(Math.random() * chars.length));
       return id;
    };

    var id = randomID();

    //Adding placeholder element
    document.write('<div id="' + id + '"></div>');

    //Injecting new element instead of placeholder
    var placeholder = document.getElementById(id)
    placeholder.parentNode.replaceChild(element, placeholder);
};
Jinx
  • 857
  • 2
  • 14
  • 28
0

Use document.currentScript and fallback to document.scripts[document.scripts.length-1] if you're targetting IE

function writeHere(element)
{
 var sc = document.currentScript || document.scripts[document.scripts.length-1] ;  
 sc.parentNode.insertBefore(element, sc);
 // or in jquery $(sc).before($(element));
}

note: I didn't test document.scripts[document.scripts.length-1] thoroughly but it should work in most cases (= if you don't create script element by hand in other scripts).
And this is a fix for IE so who cares :)

frenchone
  • 1,547
  • 4
  • 19
  • 34