jquery: jQuery 3 - window load inside ready state will not be triggered

Description

In jQuery 3.0.0 I got the issue, that a window load callback inside a ready state gets not triggered anymore. I think this is because it’s async since 3.0.0. But this is used in jQuery plugins, to be only executed after all page content is loaded. And this is often wraped in a ready state by users.

Example Code

https://jsfiddle.net/vpm59qws/

$(function() {
    $(window).on("load", function() {
        console.log("this will not be triggered");
    });
});

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Comments: 28 (18 by maintainers)

Commits related to this issue

Most upvoted comments

To be clear, we understand what’s causing this. We recently made ready handlers fire asynchronously. This has advantages that are hard to give up. The disadvantage is that the ready handler can sometimes fire after the load event if the load event fires quickly enough. The side effect you’re seeing in this issue is that you’re binding a load event handler after the load event has already fired.

The fix is to bind the load outside of ready.

$(function() {
  // Things that need to happen when the document is ready
});

$(window).on("load", function() {
  // Things that need to happen after full load
});

@timmywil Agreed, and that ensures that the onload runs at all. However, it doesn’t ensure that the ready code always and consistently runs before the onload code. I can imagine situations where that might be important, for example a plugin that initializes its DOM on ready but does some further work once the page has loaded entirely. We can recommend solutions for that but we need to document it. We should also determine whether there are cases that become hard to write (or existing code causing widespread breakage) because of the situation.

$(window).on("load", function(){
   $.ready.then(function(){
      // Both ready and loaded
   });
})

You’re not adding any additional information here. Please stop. The reason it never executes is because ready occurs after the one-time load event occurs.

It’s not the problem that it is late or async. The problem is, that it will be executed never! It makes v3 pretty useless in my eyes, like for plugin developers. Because you can’t prevent users to do things in a ready state. And such essential as a load event should always work.

I’m currently thinking about how to solve this even on an async execution. Maybe like tracking the load event within the library itself, and when something is bind to load afterwards, it will be executed immediately.

In particular, if a plugin or other jQuery code is lazy-loaded on a page after the both the DOMContentLoaded and load events have fired, the plugin would never see the load event. The ready code will run of course, since it’s not an event but instead a state. I think that makes this behavior enough of an anti-pattern that we shouldn’t try to encourage it.

It’s definitely not best practice to wrap everything in a ready. Things that can be done outside a ready should be done there, such as initializing ajax requests, so you don’t introduce unneeded delays. Similarly you can’t “execute all features” just because the HTML document is ready.

The tickets open because I also believe that there could be issues with this, but we’d prefer to act on evidence rather than incorrect assertions. See also gh-3197.