2.1 <script>元素
<script>元素的主要属性:
1.async:表示应该立即开始下载脚本,但不能执行其他页面工作,这代表async脚本的执行会阻塞页面的渲染,但是下载不会
2. defer:表示在文档解析和显示完成之后再执行脚本,所以是在页面解析渲染完毕后,defer脚本才执行
总的来说,defer和async属性都是异步去加载外部的JS脚本文件,他们都不会阻塞HTML页面的解析,区别如下表:
async | defer | |
适用场景 | 不依赖DOM或其他脚本 | 依赖DOM或其他脚本 |
执行顺序 | 不能保证按加载顺序执行 | 按加载顺序执行 |
3. type:表示代码块当中脚本语言的内容类型(也称MIME类型),一般是"application/x-javascript",如果是"module",则代码会被当成是ES6模块,只有这个时候代码中才能出现import和export关键字。
4. src:引入外部脚本,如
<script src="example.js"></script>
需要注意的是,使用了src的<script>标签中不应再包含其他代码,如果有的话,浏览器也只会下载并执行脚本文件,从而忽略行内代码。
src还可以接受一个完整的url作为参数,浏览器在解析这个资源的时候就会向src属性指定的路径发送一个GET请求,初始请求不受浏览器同源策略限制。
2.1.1 标签位置
现在的Web应用为了不影响其他资源的加载,通常将所有的JavaScript引用放在<body>元素中的页面内容后面。
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
</head>
<body>
<!-- 页面内容 -->
<script src="example.js"></script>
</body>
</html>
2.1.2 推迟执行脚本
defer脚本会在浏览器解析到结束的</html>标签之后才会执行,只对外部脚本文件才有效,并且都会在DOMContentLoaded事件之前执行。
2.1.3 异步执行脚本
async脚本的目的是不必等待脚本下载和执行完之后再加载页面,下载脚本之后立即执行,不过重点在于两个async脚本之间不能有依赖关系,也不应该在加载期间修改DOM。异步脚本保证会在页面的load事件之前执行,但是与DOMContentLoaded的执行顺序没有关系。
2.1.4 动态执行脚本
使用JS创建一个script脚本,并将它添加到head的子元素中去。
let script = document.createElement('script');
script.src = 'global.js';
document.head.appendChild(script);
所以在把这个元素添加到DOM且执行到这段代码之前不会发送请求,相当于是默认添加了async属性。
2.1.5 XHTML中的变化
略。
2.1.6 废弃的语法
略。
2.2 行内代码与外部文件
与行内的JavaScript代码相比,外部脚本文件的优点是可维护性、缓存、适应未来。
2.3 文档模式
可以使用文档开头的doctype切换文档模式,主要有两种,一种是混杂模式一种是标准模式,混杂模式在所有浏览器当中都以省略doctype声明作为开关。
2.4 <noscript>元素
这是一个页面优雅降级的处理方案,用于给不支持JavaScript的浏览器提供替代内容,在下列两种情况下,浏览器将渲染包含在<noscript>中的内容:
- 浏览器不支持脚本
- 浏览器对脚本的支持被关闭
2.5 小结
- 要包含外部JavaScript文件,必须将src属性设置为要包含文件的URL。 文件可以跟网页在一台服务器上, 也可以位于完全不同的域。
- 所有<script>元素会依照它们在网页中出现的次序被解释。在不使用defer和async属性的情况下,包含在<script>元素中的代码必须严格按次序解释。
- 对不推迟执行的脚本,浏览器必须解释完位于<script>元素中的代码,然后才能继续渲染页面的剩余部分。为此,通常应该把<script>元素放到页面末尾,介于主内容之后及</body>标签之前。
- 可以使用defer属性把脚本推迟到文档渲染完毕后再执行。推迟的脚本总是按照它们被列出的次序执行。
- 可以使用async属性表示脚本不需要等待其他脚本,同时也不阻塞文档渲染,即异步加载,异步脚本不能保证按照它们在页面中出现的次序执行。
- 通过使用<noscript>元素,可以指定在浏览器不支持脚本时显示的内容。如果浏览器支持并启用脚本,则<noscript>元素中的任何内容都不会被渲染。