user2693017
user2693017

Reputation: 1860

Running javascript when the DOM is modifyable/interactive

we have javascript code that injects elements into the DOM. Therefore it needs to wait until the DOM is in the required state.

We use the following for this:

document.onreadystatechange = function () {
    if (document.readyState === "interactive") {
        if (!tagsPlaced)
            placeTags();
    }
};

var DOMReady = function(a,b,c){b=document,c='addEventListener';b[c]?b[c]('DOMContentLoaded',a):window.attachEvent('onload',a);};
DOMReady(function () {
    if (!tagsPlaced)
        placeTags();
});

When there is a site with a slow or not loading script, it never fires these events..

The site is fully useable from the user perspective, and if we call "placeTags" manually it works as well.

One solution would be to call "placeTags" from the footer of the page. Unfortunately, we need to support loading the javascript anywhere on the page.

What can be done?

Upvotes: 1

Views: 47

Answers (1)

T.J. Crowder
T.J. Crowder

Reputation: 1074268

Use the defer attribute on the script tag for the code, and run your code immediately when your script is evaluated, rather than waiting. All even vaguely-modern browsers (including IE10 and IE11) support the defer attribute:

<script src="/path/to/your/script" defer></script>

If for some reason you can't do that (or can't rely on it being done), you can detect what it is that placeTags needs (whatever that is) and use a setTimeout loop until/unless that thing appears. For instance, if you needed to wait for a particular element to show up in the DOM, that might look like this:

(function boot(retries) {
    if (/*...condition your script needs is met...*/) {
        placeTags();
    } else {
        if (--retries <= 0) {
            // Give up, it's been at least a minute (100ms * 600 retries)
        } else {
            // Try again in 100ms
            setTimeout(boot, 100, retries);
        }
    }
})(600);

Upvotes: 2

Related Questions