0%

JavaScript学习笔记(2)

《JavaScript高级程序设计》第二章,在HTML中使用JavaScript。


<script>元素

属性

  • async
    可选,只对外部脚本文件有效,表示应该立即下载脚本,但不妨碍页面中的其他操作,如下载其他资源或等待加载其他脚本。

  • defer
    可选,只对外部脚本文件有效,表示脚本可以延迟到文档被完全解析和显示后再执行。

  • charset
    可选,多数浏览器忽略其值,表示通过src属性指定的代码的字符集。

  • src
    可选。一般外部JavaScript文件带有.js拓展名,但这不是必须的,因为浏览器不会检查包含JavaScript的文件的拓展名。所以也可以用JSP、PHP或其他服务器端语言动态生成JavaScript,不过这种情况下由于不是.js拓展名了,需要确保服务器能返回正确的MIME类型。带有src属性的script标签内若有inline JavaScript,则会只下载并执行外部script,忽略嵌入script。

  • language
    已废弃,多数浏览器忽略其值,表示使用的脚本语言,如JavaScript、VBScript等。

  • type
    可选,可看成language属性的代替属性,表示使用的脚本语言的内容类型(即MIME类型)。默认值为text/javascript但其已过时了,在过渡期间使用了application/x-javascript,直到最新的标准中使用application/javascript

* async vs defer

regular

  • 过程
    • 解析HTML时遇到<script>标签立刻停止解析并等待
    • 下载script
    • 运行script
    • 等待结束,继续解析HTML
  • 注意
    • scripts的执行顺序和页面中的出现顺序一致
  • 存在问题
    • script无法看到其下方的DOM元素,因此也无法对其进行处理
    • 如果HTML靠前的位置存在庞大的script,HTML的解析会阻塞很久,用户要等很久才能看到页面内容
  • 解决办法
    • 将<script>标签置于HTML底部(即</body>正上方),不过还是存在阻塞问题
    • 使用async和defer属性

async

  • 过程
    • 解析HTML不会被<script>标签打断,而是并行地解析HTML和下载script
    • 如果script下载完毕则script立刻执行
    • script在执行时不能进行HTML的解析(这里讲的三种情况都是这样)
  • 注意
    • HTML的解析不会被script的下载阻塞,页面内容立即显示
    • scripts的执行顺序取决于谁先下载完(load-first order),是不可预测的
    • DOMContentLoaded事件的触发和script无关

defer

  • 过程
    • 解析HTML不会被<script>标签打断,而是并行地解析HTML和下载script
    • 当解析HTML结束时运行script
    • 触发DOMContentLoaded事件
  • 注意
    • HTML的解析不会被script的下载阻塞,页面内容立即显示
    • scripts的执行顺序和页面中的出现顺序一致
    • 如果<script>标签无src则defer属性会被忽略

reference

* dynamic script

1
2
3
let script = document.createElement('script');
script.src = "/xxx.js";
document.body.append(script);// (*)
  • 过程
    • script被附加到文档中(*)后立即加载
    • 默认表现为async
    • 若想阻止默认行为可在(*)前添加script.async = false,此时表现为regular

<noscript>元素

早期浏览器有些不支持JavaScript,为了让页面平稳地退化引入了<noscript>元素。该标签内包含的内容只有在下列情况中显示:

  • 浏览器不支持脚本
  • 浏览器支持脚本,但脚本被禁用

其他情况下浏览器不会显示<noscript>标签中的内容。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>

<body>
<noscript>
<p>本页面需要浏览器支持/启用JavaScript</p>
</noscript>
</body>

</html>