【问题标题】:Why is my 'load' event/function not beeing executed after switching to jQuery 3?为什么在切换到 jQuery 3 后我的“加载”事件/函数没有被执行?
【发布时间】:2016-09-16 21:47:12
【问题描述】:

自从我从 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!");
    });
});

【问题讨论】:

    标签: javascript jquery jquery-plugins jquery-3


    【解决方案1】:

    使用/切换到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);
    

    如果开发人员/用户现在将插件初始化包装在 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,因为其他用户/不同的浏览器可能会遇到这个问题。其他人可能会遇到问题,因为它是asynchron,您永远无法知道您的代码何时/是否被执行...

    【讨论】:

    • 对不起,我不明白你的评论。你能解释一下你的意思吗? @CeylanMumunKocabaş
    • 你解释得很好,这也是可以理解的,即使我不想理解——我会的,我知道了吗?
    • 你确定这是 jq3 的新特性吗?因为它仍在使用内部就绪的延迟对象。您描述的行为可以在 jq1.x - 2.x 中复制。所以为了更清楚,你能提供一个在 jq3.0 中失败的旧 jq 版本的示例吗?你有关于 jq3.x 中这个变化的链接吗?谢谢编辑:我看到了一些变化,在它使用承诺之前,现在在 jq3 中,它正在使用延迟对象,但我不确定是否有任何更深层次的变化
    • 我真的可以说它是新的。我在 GitHub 上有一个名为 Lazy 的插件,自从 jQuery 3 推出以来,我就遇到了很多这样的问题,因为我在初始化时使用了 load。这是一个未解决的问题:github.com/eisbehr-/jquery.lazy/issues/55。我什至与 jQuery 核心团队讨论过这个问题,他们说这是一个“真正的问题”并且是 jQuery 3 的新问题,因为发生了变化(甚至在发行说明中也有说明)。你可以在这里阅读:github.com/jquery/jquery/issues/3194。稍后我可以为此创建一个示例,如果仍然需要...
    • 这绝对是很好的链接。非常感谢,非常感谢!
    猜你喜欢
    • 2016-11-29
    • 1970-01-01
    • 1970-01-01
    • 2013-02-28
    • 1970-01-01
    • 2018-08-15
    • 2017-09-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多