HOWTO · HTML
将 JavaScript 文件链接到 HTML 文件
本教程介绍如何将 JavaScript 文件链接到 HTML 文件
本页内容
要将 JavaScript 添加到 HTML 页面,请加入一个 <script> 元素。使用它的 src 属性加载单独的 .js 文件,或在开始和结束标签之间写一段简短脚本。对于大多数需要操作 DOM 的页面脚本,可将外部脚本放在 <head> 中并添加 defer;如果脚本彼此独立且执行顺序无关紧要,则使用 async。
使用 src 链接外部 JavaScript 文件
创建一个 JavaScript 文件,并在 HTML 文档中引用它。例如,如果 index.html 和 app.js 位于同一目录,下面的页面就会加载 app.js:
本节中的代码以及显示的标签或输出仍为英文。
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>External script example</title>
<script src="./app.js" defer></script>
</head>
<body>
<h1 id="message">Waiting for JavaScript</h1>
</body>
</html>
./app.js 是一个 URL 路径,相对于 HTML 文档的 URL 解析,而不是相对于你电脑上 JavaScript 文件的位置或服务器的工作目录。如果文件位于页面旁边的 js 子目录中,请使用 ./js/app.js。请确保大小写和拼写完全一致;在不区分大小写的开发环境中可用的路径,在区分大小写的服务器上可能会失效。以斜杠开头的路径(例如 /js/app.js)则从网站的 URL 根目录开始解析。
defer 属性允许浏览器在解析 HTML 时下载文件,并在解析完成后运行脚本。这样,脚本查找标题元素时,该元素就已经存在。若多个页面共用该文件,或希望 HTML 与 JavaScript 分开维护,请保留独立的脚本文件。
运行此示例:
console.log("JavaScript loaded");
这个简短的 JavaScript 示例独立演示了脚本向浏览器控制台输出消息。在页面示例中,app.js 可以使用 document.querySelector("#message") 查找元素;如果该元素存在,就将其 textContent 设为 "JavaScript is connected"。这个带检查的 DOM 更新是针对页面场景的改写,并不表示运行时已产生该结果。
直接在 HTML 页面中添加 JavaScript
如果某段短小的行为只用于一个页面,可以直接在 <script> 元素中编写 JavaScript。将该元素放在它所需标记之后,通常就在 </body> 之前:
本节中的代码以及显示的标签或输出仍为英文。
<body>
<h1 id="message">Waiting for JavaScript</h1>
<script>
const message = document.querySelector("#message");
if (message) {
message.textContent = "Inline JavaScript is connected";
}
</script>
</body>
浏览器解析完标题后才会执行脚本,因此查询时能够找到该元素。内联代码适合简单的页面专属操作;随着代码增长,外部文件更便于复用、缓存和维护。不要使用 document.write 来进行常规页面更新:解析完成后调用它可能会替换整个文档。应使用 textContent 等 DOM 方法安全地修改元素。
选择外部脚本的运行时机
放在 <head> 中的普通外部脚本会在下载和执行期间暂停 HTML 解析。如果脚本立即查询 body 中的元素,该元素此时尚未解析。放在 <body> 末尾附近的脚本会在前面的标记解析完成后运行,这可能适合较小的页面;但浏览器仍会在该脚本下载和运行期间暂停解析。
对于通常需要操作 DOM 的文件,将 <script src="./app.js" defer></script> 放在 <head> 中是一个清晰的默认选择。带 defer 的外部脚本会与 HTML 解析并行下载,然后在解析完成后按文档顺序执行。如果一个延迟执行的文件依赖另一个文件,请先列出被依赖的文件。defer 适用于外部脚本;给内联脚本添加它并不会推迟内联代码的执行。
如果文件彼此独立,例如独立的分析脚本,可使用 <script src="./analytics.js" async></script>。它会与 HTML 解析并行下载,并在准备就绪后立即执行,因此可能在解析完成前运行。异步脚本的执行顺序没有保证,也可能在页面元素尚未就绪时运行,因此不要将此方式用于依赖其他脚本或已解析 DOM 的脚本。async 和 defer 都用于外部脚本;在现代浏览器中,如果两者同时存在,async 的行为优先。
检查脚本路径和页面行为
如果页面没有任何反应,先检查准确的 src 值以及 HTML 页面是从哪里提供的。打开浏览器开发者工具,在 Network 面板中查看脚本请求:未找到响应通常表示路径、文件名或字母大小写有误。Console 面板会显示 JavaScript 语法错误和运行时错误。修正后重新加载页面,以查看当前请求和消息。
如果请求成功但页面没有变化,请检查脚本查询的元素 ID 是否正确,以及脚本运行时相关标记是否已经存在。对于依赖 DOM 的外部脚本,可在 head 中添加 defer;对于较小的内联脚本,可将它移到目标元素之后。如果多个脚本会互相影响,优先使用按依赖顺序排列的延迟脚本,而不是异步加载。下载成功只能说明浏览器找到了该文件,并不能证明脚本运行时没有出错。
常见问题
JavaScript 文件链接应该放在哪里? 对于通常会使用页面 DOM 的外部脚本,可将它放在 <head> 中并添加 defer。放在 body 末尾的脚本也能访问前面已有的标记,而没有特殊属性的 head 脚本会在 body 解析之前运行。
defer 有什么作用? 它会在不暂停 HTML 解析的情况下下载外部脚本,然后在解析完成后,按延迟脚本出现的顺序执行。
一个页面可以链接多个 JavaScript 文件吗? 可以。每个文件添加一个 <script src="..." defer></script> 元素即可。带 defer 的文件按文档顺序执行,因此应先列出共享依赖,再列出使用这些依赖的文件。
async 和 defer 有什么区别? 两者都允许并行下载。defer 会等到解析完成后再执行,并保留文档顺序;async 会在每个文件准备就绪后立即执行,不保证顺序。
我需要设置 type="text/javascript" 吗? 不需要。在 HTML5 中,<script> 元素默认使用 JavaScript,因此普通 JavaScript 脚本不需要 type 属性。