本篇笔记示例代码仓库:https://github.com/zhangtuo1999/study-js。
本篇笔记遵循中文技术文档的写作规范。
主要内容来源于《JavaScript高级程序设计(第4版)》,部分内容来源于MDN Web Docs。
HTML中的JavaScript
1 <script>
元素
使用 <script>
元素在 HTML 中插入 JavaScript。
<script>
元素的属性:
-
async
:(可选)表示应该并行下载该脚本并尽快解析执行。只对外部脚本文件生效。这是一个布尔属性,存在即为 true 值,缺失即为 false 值。 -
crossorigin
:(可选)配置相关请求的 CORS 设置。可选值 描述 anonymous 对此元素的 CORS 请求将不设置凭据标志。 use-credentials 对此元素的 CORS 请求将设置凭证标志;这意味着请求将提供凭据。 “” 设置一个空的值,如 crossorigin
或crossorigin=""
,和设置anonymous
的效果一样。 -
defer
:(可选)表示应该在文档完成解析后执行该脚本。只对外部脚本文件生效。布尔属性。 -
integrity
:(可选)表示允许将接受到的资源签名和指定的加密签名进行比对,用来验证子资源的完整性。如果收到的资源签名和该属性指定的签名不匹配,则页面报错并且不会执行脚本。 -
src
:(可选)引用外部脚本的 URI,用来代替在文档中插入脚本。 -
type
:(可选)指定脚本语言的内容类型(MIME 类型)。缺失会被视为 JavaScript。
注意:
- 使用
src
属性的<script>
元素不应该在标签中包含其它代码。如果两者都提供,浏览器只会下载并执行脚本文件,不会执行标签中的代码。 - 如果
src
是一个完整的 URL,那么浏览器会向这个 URL 发送一个 GET 请求,以获取响应的资源。这个请求不受同源策略的限制,但是获取到的 JavaScript 是受同源策略限制的。
1.1 标签位置
通常将所有的 JavaScript 引用放在<body>
元素中、页面内容的后面。例如:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
</head>
<body>
<!-- 这里是页面内容 -->
<script src="... ..."></script>
<script>
// ... ...
</script>
</body>
</html>
这样,页面内容会在处理 JavaScript 前渲染,减少了页面空白时间。
1.2 推迟执行脚本
如果<script>
标签使用了defer
属性,就表明了该脚本不会对文档进行修改。因此,浏览器在整个页面解析完成后再去执行脚本。如果<script>
标签使用了defer
属性,浏览器会立即下载脚本,但是推迟执行。例如:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script defer src="... ..."></script>
</head>
<body>
<!-- 页面内容 -->
</body>
</html>
这个例子中,虽然script
标签写在head
标签内部。但是因为其具有defer
属性,浏览器会解析完全部文档后再去执行该脚本。
注意:
如果有两个defer
属性的脚本,浏览器会按照次序去顺序执行。
1.3 异步执行脚本
async
属性和defer
属性类似,都只适用于外部脚本,并告诉浏览器立即下载。但是和defer
不同的是,标记为async
的脚本不保证按出现的次序去执行。例如:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!-- 页面内容 -->
<script async src="... ..."></script>
<script async src="... ..."></script>
</body>
</html>
这个例子中,第二个脚本未必在第一个脚本之后执行。
1.4 动态加载脚本
除了使用script
标签,还可以通过向 DOM 中动态添加script
元素的方式加载指定脚本。例如:
let script = document.createElement("script");
script.src = "https://cdn.bootcdn.net/ajax/libs/vue/3.2.33/vue.cjs.js";
document.head.appendChild(script);
注意:
-
默认情况下这种方式是异步形式进行加载的,相当于加上了
async
属性。 -
以这种形式获取的资源对浏览器预加载器是不可见的。想要让预加载器知道这些动态请求文件的存在,可以在文档的头部进行显式声明。
<link rel="preload" href="https://cdn.bootcdn.net/ajax/libs/vue/3.2.33/vue.cjs.js">
1.5 废弃的语法
type
属性使用一个 MIME 类型字符串来标识script
的内容。浏览器默认使用 JavaScript。除非特殊情况,否则最佳做法是不指定type
属性。
2 行内代码和外部文件
虽然可以在 HTML 中嵌入 JavaScript 代码,但是最佳实践时尽可能将 JavaScript 代码放在外部文件中。优点有:
- 可维护性。使用一个目录保存所有 JavaScript 代码,比将 JavaScript 代码分散到各个 HTML 中更容易维护。
- 缓存。浏览器可以缓存所有外部链接文件。如果两个页面用到了同一个文件,那么浏览器就可以从缓存中加载该文件。
3 <noscript>
元素
noscript
元素可以包含在任何出现在body
中的 HTML 元素,<scrpit>
除外。在下面两种情况下,浏览器将显示包含在noscript
中的内容:
- 浏览器不支持脚本。
- 浏览器对脚本的支持被禁用。