为什么我的 'load' event/function 切换到 jQuery 3 后没有执行?

Why is my 'load' event/function not beeing executed after switching to jQuery 3?

由于我已从 jQuery 1.x / jQuery 2.x 升级到 jQuery 3.x,我现有的代码将无法再正确执行。一切正常,但 load 事件侦听器不再被触发或只是有时被触发:

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

当 using/switching 到 jQuery 3 时可能会出现此问题。这是因为新 jQuery 3 中的所有 ready states 现在已完全 asynchron。这意味着,没有给定的代码执行顺序。

因此,可能会发生 load 在 之前 被触发,您的 ready state 已被执行。当您的 ready 函数现在终于被触发时,您的 load 侦听器为时已晚,将不会被执行。


jQuery 用法:

要更改此行为,只需删除 load 事件侦听器初始化周围的 ready state。不需要用 ready 函数封装它。你可以在没有的情况下初始化它们。

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

如果您需要或想要注册这两个事件,您可以自己注册load事件并在ready state内部决定下一步要做什么。

// 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 插件:

另一种情况是 jQuery 插件,它也使用 load 事件。例如:

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

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

如果 developer/user 现在将插件初始化包装在 ready state 中,问题可能会再次发生,就像之前解释的那样:

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

一个解决方案是自行跟踪插件中的 load 事件,突破 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);

结论:

即使这个问题没有发生在你身上,在你的测试中,你应该立即更改那些代码,当使用 jQuery 3 时,因为其他 users/different 浏览器可以 运行 进入这个麻烦.其他人可能遇到了问题,因为它是 asynchron,你永远不会知道 when/if 你的代码被执行了......