Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to reliably insert a HTML element at script's location?

I'm writing a Javascript file which will be a component in a webpage. I'd like it to be simple to use - just reference the script file in your page, and it is there. To that end however there is a complication - where should the HTML go that the Javascript generates? One approach would be to require a placeholder element in the page with a fixed ID or class or something. But that's an extra requirement. It would be better if the HTML was generated at the location that the script is placed (or, at the start of body, if the script is placed in head). Also, for extra customizability, if the fixed ID was found, the HTML would be placed inside that placeholder.

So I'm wondering - how do I detect my script's location in the page? And how do I place HTML there? document.write() comes to mind, but that is documented as being pretty unreliable. Also it doesn't help if the script is in the head. Not to mention what happens if my script is loaded dynamically via some AJAX call, but I suppose that can be left as an unsupported scenario.

like image 856
Vilx- Avatar asked Nov 04 '22 11:11

Vilx-


1 Answers

I am doing that with this code...

// This is for Firefox only at the moment.
var thisScriptElement = document.currentScript,

// Generic `a` element for exploiting its ability to return `pathname`.
    a = document.createElement('a');


if ( ! thisScriptElement) {
    // Iterate backwards, to look for our script.        
    var scriptElements = document.body.getElementsByTagName('script'),
        i = scriptElements.length;

    while (i--) {
        if ( ! scriptElements[i].src) {
           continue;
        }

        a.href = scriptElements[i].src;
        if (a.pathname.replace(/^.*\//, '') == 'name-of-your-js-code.js') {
            thisScriptElement = scriptElements[i];
            break;
        }
    }
}

Then, to add your element, it's simple as...

currentScript.parentNode.insertBefore(newElement, currentScript);

I simply add a script element anywhere (and multiple times if necessary) in the body element to include it...

<script type="text/javascript" src="somewhere/name-of-your-js-code.js?"></script>

Ensure the code runs as is, not in DOM ready or window's load event.

Basically, we first check for document.currentScript, which is Firefox only but still useful (if it becomes standardised and/or other browsers implement it, it should be most reliable and fastest).

Then I create a generic a element to exploit some of its functionality, such as extracting the path portion of the href.

I then iterate backwards over the script elements (because in parse order the last script element should be the currently executing script), comparing the filename to what we know ours is called. You may be able to skip this, but I am doing this to be safe.

like image 86
alex Avatar answered Nov 12 '22 15:11

alex