在哪种情况下可以将HTML标记中的脚本标签包含在head标签中而不使用异步和延迟属性?

时间:2018-07-12 22:57:24

标签: javascript html web

大家好,我是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源代码,只是在任何地方都看不到异步和延迟属性?

2 个答案:

答案 0 :(得分:2)

所以这里有一些启发。

  1. 从这一点开始,在HTML中使用<script></script>而没有任何额外的属性将阻止HTML解析(即“将html加载到浏览器窗口”)。成功下载后,将提取指定的脚本并执行。之后,将恢复执行(将加载页面)。
  2. 使用<script async></script>允许HTML解析器在下载脚本之前不阻止解析。
  3. 使用<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);