3

I want to disable some specific "feature" that one my plugins does to the DOM when the DOM is ready.

If I put my code inside the onload callback, will it always get executed after the ready callback?

I want to be sure in 100% that even if there aren't any images of just few the ready will be executed before the onload.

gdoron
  • 147,333
  • 58
  • 291
  • 367

3 Answers3

3

While I think @jAndy's answer is right, you can afford yourself some extra assurance by also placing the code in the onload within a ready() call.

Just make sure that your main ready() call comes first.

$(document).ready(function() {
    // Your normal ready handler
});

$(window).load(function() {
    // Placing code in another .ready() call in here will add it to the
    //    end of internal Array of ready handlers if any are pending
    $(document).ready(function() {
        // my onload code
    });
});

So if the ready() has already fired by the time the onload fires, your onload code will still run. (An internal flag is set once the DOM is ready, so future .ready() calls are immediately invoked.)

If the .ready() has somehow not fired when the onload happens, that will mean that your original ready() code is first in the internal Array, and the new .ready() code will be added to the end of the Array.


EDIT:

Looking at the source for the main jQuery.ready handler that is fired when the DOM is ready (which in turn, fires the list of the user's .ready() handlers), it appears as though there's an IE bug where the handler fires a little early.

To remedy this bug, jQuery makes the handler asynchronously invoked until it can actually see document.body.


ready: function (wait) {
    // Either a released hold or an DOMready/load event and not yet ready
    if ((wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady)) {

        // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
        if (!document.body) {
            return setTimeout(jQuery.ready, 1);
        }

        // Remember that the DOM is ready
        jQuery.isReady = true;

        // If a normal DOM Ready event fired, decrement, and wait if need be
        if (wait !== true && --jQuery.readyWait > 0) {
            return;
        }

        // If there are functions bound, to execute
        readyList.fireWith(document, [jQuery]);

        // Trigger any bound ready events
        if (jQuery.fn.trigger) {
            jQuery(document).trigger("ready").off("ready");
        }
    }
},

It would seem that because of this asynchronous looping of the handler, then IE would at least be possibly prone to having the window.onload handler invoked before the .ready() handlers.

Adding to the .ready() handler list within the onload as I described above should remedy this.

Community
  • 1
  • 1
  • @gdoron: Taking a quick [look at the source](https://github.com/jquery/jquery/blob/1.7.1/src/core.js#L400-403), it appears as though there's an IE bug where the native DOM ready fires a little early. To resolve this, jQuery asynchronously loops its main `jQuery.ready` function until it sees the `document.body`. Because this is asynchronous, it would seem that there would be a very real chance that the `onload` could happen first. All that to say that placing your code in the `.ready()` as I've shown is probably going to be your safest bet. :) –  Feb 12 '12 at 14:55
1

Yes.

  • onload will fire when anything else was loaded (images, frames, iframes, etc.),
  • DOMContentLoaded will fire as soon as the DOM tree can get accessed.
jAndy
  • 231,737
  • 57
  • 305
  • 359
  • And if don't any images or there are just few? I want to be sure in 100% – gdoron Feb 12 '12 at 13:53
  • @gdoron: well I can't find any "official" spec or documentation about event order currently. But I'm 99,9% sure that `DOMContentLoaded` (when supported) will always fire before `load` regardless if there are images, iframes etc. available. – jAndy Feb 12 '12 at 13:56
  • As @jAndy mentioned, yes, **onload** will fire after the **ready** event because **ready** is fired when the DOM is there and **onload** waits for all the assets (images etc) to load. Have a look at http://api.jquery.com/ready/ – T. Junghans Feb 12 '12 at 13:58
0

No. Just try it out for yourself: Create a large HTML file, strip every dependent resource (images, scripts, stylesheets) and test.

enter image description here

Load fires when every resource is fetched from the internet. DOMContentLoad fires when the HTML is fetched and parsed. The latter took 14 ms in my test with 140 KB HTML code. Sure, that's an edge case, but there is no guarantee that load fires before DOMContentLoaded - not even with external resources (due to caching, parallel downloads with HTTP/2, fast connections).

wortwart
  • 3,139
  • 27
  • 31
  • Did you also try it with `console.log`? Or are you relying solely on the developer tools UI? – gdoron Jul 19 '17 at 09:18
  • That's the result of the developer tools which should be more precise than JavaScript that has to be parsed, compiled, and executed. Interestingly, I saw this effect only in Chromium-based browsers, not in Edge or Firefox. – wortwart Jul 20 '17 at 12:40
  • Tests with console.log actually fire onload after DOMContentLoaded, also in Chromium. I wouldn't rely on that anyway. – wortwart Jul 20 '17 at 12:48