use*_*782 44 html javascript jquery deferred-execution
我有以下HTML代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/blazy/1.8.2/blazy.min.js" defer></script>
<script src="https://code.jquery.com/jquery-2.1.4.min.js" integrity="sha256-8WqyJLuWKRBVhxXIL1jBDD7SDxU936oZkCnxQbWwJVw=" crossorigin="anonymous" defer></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lightbox2/2.9.0/js/lightbox.min.js" defer></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous" defer></script>
<!-- 26 dec flexslider js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/flexslider/2.6.3/jquery.flexslider.min.js" defer></script>
<script defer>
(function($) {
$(document).ready(function() {
//do something with b-lazy plugin, lightbox plugin and then with flexslider
});
})(jQuery);
</script>
</head>
<body>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
我收到一个错误,说没有定义jQuery.现在,即使我从我的内联JS代码中删除defer,它也说jQuery是未定义的.出于某种原因,我必须将jQuery插件保留在头部并保持我的JS代码内联.我的问题是:
为什么内联Javascript代码在defer
属性存在时不会延迟?
有没有办法模仿我的内联Javascript代码的延迟行为?如果需要,我可以将它放在body标签的末尾.
tri*_*cot 83
具有defer
属性的脚本按照指定的顺序加载,但在加载文档之前不会加载.至于defer
有没有影响script
的标签,除非他们也有src
属性,首先执行的脚本是你的嵌入式脚本.所以当时jQuery尚未加载.
您可以通过至少两种方式解决此问题:
将您的内联脚本放在一个.js
文件中,并使用一个src
属性(除了defer
您已经拥有的属性之外)引用它,或者
让您的内联脚本等待文档和加载的延迟脚本.该DOMContentLoaded
事件将触发时发生:
<script>
window.addEventListener('DOMContentLoaded', function() {
(function($) {
//do something with b-lazy plugin, lightbox plugin and then with flexslider
})(jQuery);
});
</script>
Run Code Online (Sandbox Code Playgroud)注意:请注意,在后一种情况下$(document).ready(function()
不再包括,因为它将等待相同的事件(DOMContentLoaded
).您可能还包括像您在最初的代码有,但随后的jQuery只会执行回调马上,这使得没有实际的区别.
Bro*_*dan 39
您可以从脚本中创建Base64 URL并将其放入src!
<script src="data:text/javascript;base64,YWxlcnQoJ0hlbGxvIHdvcmxkIScpOw=="
defer>
</script>
Run Code Online (Sandbox Code Playgroud)
我建立了一个快速测试,看看它在行动.Hello world!
如果defer
工作正常,你应该看到一个警告:
<script defer>
alert('Why no defer?!?');
</script>
<!-- alert('Hello world!'); -->
<script src="data:text/javascript;base64,YWxlcnQoJ0hlbGxvIHdvcmxkIScpOw=="
defer></script>
<script>
alert('Buh-bye world!');
</script>
Run Code Online (Sandbox Code Playgroud)
手动完成它有点费力,所以如果您能以某种方式(Handlebars,Angular等)编译HTML,那么这将有很大帮助.
我目前正在使用:
<script src="data:text/javascript;base64,{{base64 "alert('Hello world!');"}}"
defer>
</script>
Run Code Online (Sandbox Code Playgroud)
小智 24
您还可以使用type="module"
:
<meta charset="utf-8">
<script type="module">
let t = document.getElementById('top');
console.log(t);
</script>
<h1 id="top">Top Questions</h1>
Run Code Online (Sandbox Code Playgroud)
https://developer.mozilla.org/docs/Web/HTML/Element/script#attr-type
#noLib #vanillaJS
建议不要在跨浏览器生产中使用
直到 MS IE 消亡,MS Edge 将采用 Chromium 开源;)
spec script#attr-defer(MDN 网络文档):“如果 src 属性不存在(即对于内联脚本),则不得使用此属性,在这种情况下它将不起作用。)”
规格数据_URI
使用正确的类型“text/javascript”根本不需要base64 ...;)
使用纯文本,因此您可以使用简单的:
<script defer src="data:text/javascript,
//do something with b-lazy plugin, lightbox plugin and then with flexslider
lightbox.option({
resizeDuration: 200,
wrapAround: true
})
">
Run Code Online (Sandbox Code Playgroud)
是的,这有点奇怪,但<script type="module">
默认情况下被推迟,没有其他选项可以按确切顺序混合以下内容:
来自MDN文档:
defer
此Boolean属性设置为向浏览器指示脚本应在文档解析后但在fire之前执行DOMContentLoaded
。defer属性仅应在外部脚本上使用。
这称为IIFE (立即调用函数表达式),它在DOM可用之前被执行。因此,在那种情况下jQuery
是未定义的,因为它不在DOM中。