大家好,我是JavaScript和网络开发的新手。最近,我遇到了有关脚本标记位置的问题。我知道这是一个常见问题,我在Google上也查看了关于stackoverflow的一些答案以及此样式指南。但是对于这个问题我还是不太清楚。
例如,我的html页面带有这样的外部脚本js文件
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
<script src='js.js'>
</script>
</head>
<body>
</body>
</html>
而js文件是
var loadTime = document.createElement('div');
loadTime.textContent = 'You loaded this page on: ' + new Date();
loadTime.style.color = 'blue';
document.body.appendChild(loadTime);
在我看来,这个js文件并不依赖于可用的html文件的任何DOM元素,因此我将该脚本标记放在何处都没有关系。但事实证明,我必须将此脚本标签放在正文关闭标签的底部,否则日期将不会按预期显示在页面上。另一个解决方法是在
这样的脚本标记中使用defer属性<script src='js.js' defer></script>
这让我感到困惑,如果脚本具有与DOM相关的任何操作,在我看来,如果没有defer或async属性,就无法将其放在前端的head标签内。为什么此Google样式指南https://developers.google.com/speed/docs/insights/BlockingJS仍然建议我们在head标记中编写内联脚本,因为在任何脚本文件中访问和操作DOM都非常常见。
根据http://caniuse.com/#feat=script-defer,所有浏览器中有94.59%支持此功能。 94.92%的人至少部分支持它。为什么异步和延迟属性没有得到广泛使用?我的意思是,我在那里查看了很多HTML源代码,只是在任何地方都看不到异步和延迟属性?
答案 0 :(得分:2)
所以这里有一些启发。
<script></script>
而没有任何额外的属性将阻止HTML解析(即“将html加载到浏览器窗口”)。成功下载后,将提取指定的脚本并执行。之后,将恢复执行(将加载页面)。<script async></script>
允许HTML解析器在下载脚本之前不阻止解析。<script defer></script>
可以完全解析HTML,然后将执行脚本代码。因此,从主题中回答您的问题-如果<head></head>
中的脚本不需要访问尚未存在的内容,则可以将它们包括在内(并将正常工作)。
在您的示例中,您尝试将sth附加到body(尚不存在)。
如果您在<script async></script>
中使用<head></head>
,也不能保证能正常工作。例如。脚本很小(几乎可以立即下载)-它将在html完全解析之前执行(导致访问尚不存在的内容)。我们可以为异步请求计时,这是它们的优点。
如果获取的脚本不能直接访问DOM,则使用异步是有意义的。
使用延期是有意义的,例如如果JS文件很大(例如,提取需要5秒),并且我们想向用户显示sth。在页面上。加载脚本后,我们通过脚本中的js将页面更改为它的“外观”。
请注意,这些并非都是异步和延迟的用例。
答案 1 :(得分:0)
建议您检查此load and execute order of scripts
的答案通常的方法是在head标签中仅加载javascript。 然后,在加载整个html文件之后,在文档onload中调用您的函数。
document.addEventListener('DOMContentLoaded', function() {
console.log('document - loaded - ');
//call your functions
}, true);