4

Since I've upgraded from jQuery 1.x / jQuery 2.x to jQuery 3.x, my existing code will not be executed correctly anymore. Everything works fine, but the load event listener gets not triggered anymore or just sometimes:

$(function() {
    $(window).on("load", function() {
        // this line will never/occasionally be executed
        console.log("window is loaded!");
    });
});
eisbehr
  • 12,243
  • 7
  • 38
  • 63

1 Answers1

5

The problem can be occur when using/switching to jQuery 3. It's because all ready states in the new jQuery 3 are now fully asynchron. This means, that there is no given order for your code to be executed.

Because of this, it could happen, that load is been triggered before your ready state has been executed. When your ready function now finally gets triggered, your load listener is too late and will not be executed.


jQuery Usage:

To change this behavior, just remove the ready state around your load event listener initialization. There is no need to encapsulate this with a ready function. You can initialize them without.

// $(function() {
    $(window).on("load", function() {
        // this line will now be executed again
        console.log("window is loaded!");
    });
// });

If you need or want to register both events, you can register the load event by yourself and decide inside the ready state what to do next.

// track the loading state by yourself
var windowLoaded = false;
$(window).on("load", function() {
    windowLoaded = true;
});

$(function() {
    function afterLoad() {
        console.log("loaded");
    }

    // decide inside your ready state what to do
    if( !windowLoaded ) {
        $(window).on("load", afterLoad);
    }
    else {
        afterLoad();
    }
});

jQuery Plugins:

Another case would be jQuery plugins, that uses the load event too. For example:

(function($, window) {
    $.fn.myPlugin = function() {
        $(window).on("load", start);

        function start() {
            console.log("plugin initialized and window loaded");
        }
    };
})(jQuery, window);

If a developer/user now wraps the plugin initialization in a ready state the problem could happen again, just like explained before:

$(function() {
    $("#element").myPlugin();
});

A solution would be to track the load event in your plugin on your own, to break out the ready state.

(function($, window) {
    // track the loading state beside the plugin initialization
    var windowLoaded = false;
    $(window).on("load", function() {
        windowLoaded = true;
    });

    $.fn.myPlugin = function() {
        // decide inside your plugin how to start
        if( !windowLoaded ) {
            $(window).on("load", start);
        }
        else {
            start();
        }

        function start() {
            console.log("plugin initialized and window loaded");
        }
    };
})(jQuery, window);

Conclusion:

Even when this problem not happens to you, in your tests, you should change those code immediately, when using jQuery 3, because other users/different browser can run into this trouble. Others may got the problem, because it is asynchron, you could never know when/if your code gets executed ...

eisbehr
  • 12,243
  • 7
  • 38
  • 63
  • one does will simply understand even he don't want to! – Ceylan Mumun Kocabaş Jul 26 '16 at 09:05
  • 1
    Excuse me, I don't understand your comment. Could you please explain what you mean? @CeylanMumunKocabaş – eisbehr Jul 26 '16 at 09:07
  • 1
    you explained it good and it is understandable, even if i do not want to understand it - i will, i got me know? – Ceylan Mumun Kocabaş Jul 26 '16 at 09:08
  • 1
    Are you sure this is a new feature in jq3? Because it is still using the internal ready deferred object. And the behaviour you describe can be replicated in jq1.x - 2.x. So to make it clearer, can you provide a sample working in older jq version that would fail in jq3.0? And have you any link regarding this change in jq3.x? Thank you EDIT: i see some change, before it was using a promise, now in jq3, it is using deferred object but i'm not sure about any deeper change though – A. Wolff Jul 26 '16 at 09:21
  • 1
    I really can say it is new. I have a plugin called `Lazy` on GitHub and became many of those problems since jQuery 3 is out, because I use `load` in the initialization. Here is one open issue: https://github.com/eisbehr-/jquery.lazy/issues/55. I even discussed this problem with the jQuery core team, which says that it is a 'real propblem' and new to jQuery 3, because of the changed (even noted in the release notes). You can read about it here: https://github.com/jquery/jquery/issues/3194. Later I can create an example for this, if still needed ... – eisbehr Jul 26 '16 at 09:25
  • 1
    This is definitely good links. Thank you very much, i appreciate! – A. Wolff Jul 26 '16 at 09:27