我已经在我的jQuery脚本中添加了 defer
atribute,以提高网页性能,但现在我收到了错误 $ is not defined
。页面加载时我需要执行JS代码,因此我使用jQuery.ready事件,但是使用递送时它不起作用。
<head>
<script defer="defer" src="@Url.Content("~/Scripts/jquery-1.8.2.min.js")" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
//MyLoadCode
});
</script>
</head>
存在时的延期属性指定页面完成解析后执行脚本。但是您在页面完成之前使用jQuery变量$
,当时jQuery脚本未加载且未加载,尚未初始化$
。
而不是使用延期属性,而是将脚本标签从标题移至页面底部,就在</body>
标签之前。
<html>
<head></head>
<body>
...
<script src="@Url.Content("~/Scripts/jquery-1.8.2.min.js")" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
//MyLoadCode
});
</script>
</body>
</html>
如果您不希望脚本加载到迟到,请将jQuery脚本移至HTML页面的底部。然后将其最后加载。
您需要在使用$
之前确保加载jQuery,因此您不应推迟加载JQuery。
如果要推迟加载jQuery,则需要添加使用jQuery的javascript,该JQuery在脚本Onload成功事件处理程序中。
您不能使用$(document).ready(function () {
并等待DOM已加载的单位,因为该语句是一个jQuery符号,它已递延且尚未可用。因此,仅当jQuery立即加载jQuery时,$
变量才能使用。
通常,使用明确的回调而不是轮询是清洁的,但是用defer
加载脚本的优点可以使setTimeout()
的简单调用值得。
<head>
<script defer src=https://cdn.jsdelivr.net/npm/jquery@3.6/dist/jquery.min.js></script>
<script>
const myApp = () => {
console.log('Page ready:', $('h1').text());
console.log('My app is running.');
};
</script>
<script>
const onReady = () =>
typeof $ === 'function' ? $(myApp) : setTimeout(onReady, 100);
onReady();
</script>
</head>
typeof
命令检查是否加载了 jQuery 。如果没有,请等待100毫秒,然后再次检查。(请注意,使用setTimeout()
每个呼叫onReady()
都是独立的,因此没有递归的调用堆栈溢出。)
这种投票策略不是特定于 jQuery。
您可以使用此策略等待任何库:
<script>
const onReady = () =>
typeof xLib !== 'undefined' ? myApp() : setTimeout(onReady, 100);
window.addEventListener('DOMContentLoaded', onReady);
</script>
外部JS文件
另外,您可以利用defer
脚本按顺序执行的事实,但是此需要将代码放在单独的文件中。
加载代码之前需要的库:
<head>
<script defer src=https://cdn.jsdelivr.net/npm/jquery@3.6/dist/jquery.min.js></script>
<script defer src=my-app.js></script>
</head>