mip*_*adi 1392 html javascript jquery
在JavaScript文档中嵌入JavaScript时,放置<script>
标记和包含JavaScript 的适当位置在哪里?我似乎记得你不应该把它们放在这个<head>
部分中,但放在该部分的开头<body>
也是不好的,因为在完全呈现页面之前必须解析JavaScript(或类似的东西).这似乎将该部分的末尾<body>
作为<script>
标记的逻辑位置.
所以,在这里是把正确的地方<script>
标记?
(这个问题引用了这个问题,其中建议JavaScript函数调用应该从<a>
标签移动到<script>
标签.我专门使用jQuery,但更一般的答案也是合适的.)
Bar*_*art 1742
以下是浏览器加载带有<script>
标记的网站时发生的情况:
<script>
引用外部脚本文件的标记.步骤#4会导致糟糕的用户体验.在您下载所有脚本之前,您的网站基本上会停止加载.如果有一件事是用户讨厌它正在等待网站加载.
任何脚本都可以通过document.write()
其他DOM操作插入自己的HTML .这意味着解析器必须等到脚本下载并执行才能安全地解析文档的其余部分.毕竟,脚本可以在文档中插入自己的HTML.
然而,大多数JavaScript开发人员不再操作DOM 而文档加载.相反,它们会等到文档加载后再修改它.例如:
<!-- index.html -->
<html>
<head>
<title>My Page</title>
<script type="text/javascript" src="my-script.js"></script>
</head>
<body>
<div id="user-greeting">Welcome back, user</div>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
使用Javascript:
// my-script.js
document.addEventListener("DOMContentLoaded", function() {
// this function runs when the DOM is ready, i.e. when the document has been parsed
document.getElementById("user-greeting").textContent = "Welcome back, Bart";
});
Run Code Online (Sandbox Code Playgroud)
因为您的浏览器不知道my-script.js在下载和执行之前不会修改文档,解析器会停止解析.
解决此问题的旧方法是将<script>
标记放在您的底部<body>
,因为这样可以确保解析器在最终之前不会被阻塞.
这种方法有其自身的问题:在解析整个文档之前,浏览器无法开始下载脚本.对于具有大型脚本和样式表的大型网站,能够尽快下载脚本对于性能非常重要.如果您的网站在2秒内没有加载,人们将转到另一个网站.
在最佳解决方案中,浏览器将尽快开始下载脚本,同时解析文档的其余部分.
今天,浏览器支持脚本async
和defer
属性.这些属性告诉浏览器在下载脚本时继续解析是安全的.
<script type="text/javascript" src="path/to/script1.js" async></script>
<script type="text/javascript" src="path/to/script2.js" async></script>
Run Code Online (Sandbox Code Playgroud)
具有async属性的脚本是异步执行的.这意味着脚本在下载后立即执行,同时不会阻止浏览器.
这意味着脚本2可以在脚本1之前下载并执行.
根据http://caniuse.com/#feat=script-async,94.57%的浏览器支持此功能.
<script type="text/javascript" src="path/to/script1.js" defer></script>
<script type="text/javascript" src="path/to/script2.js" defer></script>
Run Code Online (Sandbox Code Playgroud)
具有defer属性的脚本按顺序执行(即第一个脚本1,然后是脚本2).这也不会阻止浏览器.
与异步脚本不同,延迟脚本仅在加载整个文档后执行.
根据http://caniuse.com/#feat=script-defer,94.59%的浏览器支持此功能.94.92%至少部分支持它.
关于浏览器兼容性的重要说明:在某些情况下,IE <= 9可能无序执行延迟脚本.如果您需要支持这些浏览器,请先阅读此内容!
当前最先进的技术是将脚本放在<head>
标记中并使用async
或defer
属性.这样可以在不阻止浏览器的情况下尽快下载脚本.
好消息是,您的网站仍应在6%不支持这些属性的浏览器上正确加载,同时加快其他94%.
Cam*_*mel 232
就在关闭身体标签之前,如上所述
http://developer.yahoo.com/performance/rules.html#js_bottom
把脚本放在底部
脚本引起的问题是它们阻止了并行下载.HTTP/1.1规范建议浏览器每个主机名并行下载不超过两个组件.如果您从多个主机名提供图像,则可以并行执行两次以上的下载.但是,在下载脚本时,即使在不同的主机名上,浏览器也不会启动任何其他下载.
Sal*_*n A 70
非阻塞脚本标记可以放在任何地方:
<script src="script.js" async></script>
<script src="script.js" defer></script>
<script src="script.js" async defer></script>
Run Code Online (Sandbox Code Playgroud)
这样的脚本将在文档就绪后异步执行,这意味着你不能这样做:
<script src="jquery.js" async></script>
<script>jQuery(something);</script>
<!--
* might throw "jQuery is not defined" error
* defer will not work either
-->
Run Code Online (Sandbox Code Playgroud)
或这个:
<script src="document.write(something).js" async></script>
<!--
* might issue "cannot write into document from an asynchronous script" warning
* defer will not work either
-->
Run Code Online (Sandbox Code Playgroud)
或这个:
<script src="jquery.js" async></script>
<script src="jQuery(something).js" async></script>
<!--
* might throw "jQuery is not defined" error (no guarantee which script runs first)
* defer will work in sane browsers
-->
Run Code Online (Sandbox Code Playgroud)
或这个:
<script src="document.getElementById(header).js" async></script>
<div id="header"></div>
<!--
* might not locate #header (script could fire before parser looks at the next line)
* defer will work in sane browsers
-->
Run Code Online (Sandbox Code Playgroud)
话虽如此,异步脚本提供了以下优势:
可以通过使用支持回调的外部脚本来规避执行顺序问题.许多第三方JavaScript API现在支持非阻塞执行.以下是异步加载Google Maps API的示例.
And*_*are 23
如果您正在使用JQuery,那么将javascript放在最适合的地方,并使用它$(document).ready()
来确保在执行任何函数之前正确加载内容.
旁注:我喜欢该<head>
部分中的所有脚本标签,因为这似乎是最干净的地方.
All*_*nde 10
XHTML不会验证脚本是否在head元素之外的任何位置. 原来它可以无处不在.
您可以使用jQuery之类的命令来延迟执行,因此放置它的位置并不重要(除了解析期间的小性能命中).
Ama*_*mar 10
<script src="myjs.js"></script>
</body>
Run Code Online (Sandbox Code Playgroud)
脚本标记应始终在正文关闭之前使用或在HTML文件中使用底部.
然后你可以在加载js文件之前先看到页面的内容.
如果需要,请检查:http: //stevesouders.com/hpws/rule-js-bottom.php
cqu*_*zel 10
2019年的现代方法是使用ES6模块类型脚本。
<script type="module" src="..."></script>
Run Code Online (Sandbox Code Playgroud)
默认情况下,模块是异步加载和延迟的。也就是说,您可以将它们放置在任何位置,它们将并行加载,并在页面加载完成后执行。
此处描述了脚本和模块之间的区别:
与脚本相比,模块的执行描述如下:
https://developers.google.com/web/fundamentals/primers/modules#defer
支持如下所示:
https://caniuse.com/#feat=es6-module
Har*_*hil 10
放置<script>
tag</body>
的最佳位置是在关闭tag之前,因此下载和执行它不会阻止浏览器解析文档中的 html,
还加载js文件外有它自己的优势,喜欢它会被浏览器缓存,可以加快页面加载时间,它分离了HTML和JavaScript代码,并帮助更好地管理代码库。
但现代浏览器还支持一些其他的最佳方式一样async
,并defer
加载外部javascript
文件。
通常 HTML 页面执行开始一行一行。当遇到外部 JavaScript 元素时,HTML 解析会停止,直到 JavaScript 下载并准备好执行。可以使用defer
和async
属性更改此正常页面执行。
Defer
当使用 defer 属性时,JavaScript 与 HTML 解析并行下载,但只有在完整的 HTML 解析完成后才会执行。
<script src="/local-js-path/myScript.js" defer></script>
Run Code Online (Sandbox Code Playgroud)
Async
使用 async 属性时,JavaScript 会在遇到脚本时立即下载,下载后将与 HTML 解析一起异步(并行)执行。
<script src="/local-js-path/myScript.js" async></script>
Run Code Online (Sandbox Code Playgroud)
async
.async
,它们将defer
用于两者:defer
保证先执行 script1,async
则使用没有属性的async
脚本并将其置于所有脚本之上。参考资料:knowledgehills.com
这取决于。如果您正在加载页面样式/使用页面中的操作(例如单击按钮)所需的脚本,那么您最好将其放在顶部。如果您的样式是 100% CSS,并且您拥有按钮操作的所有后备选项,那么您可以将其放置在底部。
或者最好的事情(如果这不是问题)是您可以制作一个模式加载框,将 JavaScript 代码放置在页面底部,并在加载脚本的最后一行时使其消失。这样您就可以避免用户在加载脚本之前在页面中使用操作。还要避免不当的造型。
归档时间: |
|
查看次数: |
530427 次 |
最近记录: |