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
- register events on POS_END, fix for jQuery 3 (see also https://github.com/jquery/jquery/issues/3194) — committed to dmstr/yii2-bootstrap by schmunk42 6 years ago
- use jquery 2.* see also https://github.com/jquery/jquery/issues/3194 - fixes issue with CookieConsent CSS — committed to dmstr/phd5-app by schmunk42 6 years ago
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.
@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.
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.