JQuery: 延迟加载JQuery和'$未定义'

9

我对这个问题和网络上所找到的大量信息感到困惑:

在我的项目中,JQuery是使用"defer"加载的。由于项目标准,我无法更改它。

<script defer src='https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.0/jquery.min.js'></script>

现在我需要在一个页面上添加一些小功能(目前是内联的):

使用这种设置,浏览器会尝试在jQuery加载之前执行内联脚本 => "Uncaught ReferenceError: $ is not defined"。

<body>
...
...
<script>
  $("#city").change(function() {...some stuff...};
  $("#doctor").change(function() {...some stuff...};
</script>
</body>

如何聪明地解决这个问题?


让脚本执行一个回调函数,激活一个立即执行的 JavaScript 函数。 - roberrrt-s
1
添加一个常规的 onload 回调函数?请参阅 https://dev59.com/AV4d5IYBdhLWcg3wAehX - kennytm
我试图将所有内容包装在window.onload=function(){...}中,但这会破坏$(selector).change()函数..(我不明白为什么..) - caliph
3个回答

22

把它放在window.onload内,这样脚本会在所有内容完全加载后才被执行。

尝试这个例子:

window.onload = function () {
    $("#city").click(function() {
        alert('city');
    });
    $("#doctor").click(function() {
        alert('doctor');
    });
}
<script defer src='https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.0/jquery.min.js'></script>

<button id="city">City</button>
<button id="doctor">Doctor</button>

MDN中关于window.onload的解释:

load事件在文档加载过程的最后触发。此时,文档中的所有对象都在DOM中,所有图像、脚本、链接和子框架都已完成加载。

https://developer.mozilla.org/zh-CN/docs/Web/API/GlobalEventHandlers/onload


对于更符合惯用方式(在jquery中),请使用下面的代码。它与window.onload相同。

$(document).ready(function() {
    // put code here
});

另一个选择是使用$(function() { })

$(function() {
    // put code here
})

2
有点晚了,但是使用jQuery的doc ready不起作用。问题在于在jqueury加载之前$未定义,因此您无法使用它来等待其加载。我使用了您的片段,并将window.onload替换为doc ready,得到了与OP中完全相同的错误。但是window.onload可以正常工作。 - Jag
1
太棒了!非常感谢。在启用一些异步插件来提高网站速度后,它完美地解决了我的 WordPress 网站上的破损内联 JS 问题。我之前只能找到复杂的解决方案。 - eArmin
1
非常感谢。在Symfony Webpack项目的更新后,我的代码不再起作用了。现在JQuery将作为“defer”加载,因此晚于其他任何内容。所以你的“window.onload = function () {”帮了我很大忙。非常感谢! - CasualBen
@DasBen 很高兴听到这个 :) - novalagung

1
优点:采用这种方法,您不必等待“load”事件触发。只要jQuery加载完成,就应该立即执行。

var initInterval = setInterval(function(){
        if(window.jQuery) {
            clearInterval(initInterval);
            init(); // where init is the entry point for your code execution
        }
    }, 20);


function init(){
  $('#example').text('Ahoy!');
}
<script defer src='https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.0/jquery.min.js'></script>

<div id="example">Hi</div>


1

这样您就可以向window.load添加多个功能:

window.addEventListener("load",function(event) {
    $("#city").click(function() {
        alert('city');
    });
},false);

window.addEventListener("load",function(){
    $("#doctor").click(function() {
        alert('doctor');
    });
},false);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接