HTML 的 <script> 元素

1. 引言

<script> 元素是 HTML 中用于嵌入或引用 JavaScript 代码的核心标签。无论是简单的页面交互,还是复杂的前端应用,都离不开它。本文将系统讲解 <script> 元素的用法、属性、加载策略以及常见实践,帮助你写出更高效、更健壮的网页脚本。

2. 基本用法

<script> 元素有两种主要使用方式:内联脚本外部脚本

2.1 内联脚本

直接在 HTML 文件中写入 JavaScript 代码:

html 复制代码
<script>
  console.log("Hello, World!");
</script>

2.2 外部脚本

通过 src 属性引用外部的 .js 文件:

html 复制代码
<script src="js/app.js"></script>

注意 :使用外部脚本时,<script> 标签内的代码会被忽略,因此不要同时使用 src 属性和内联代码。

3. 常用属性

<script> 元素支持多个属性,用于控制脚本的加载和执行行为。

属性 说明
src 指定外部脚本文件的 URL
type 指定脚本类型,默认是 text/javascript;使用模块时设为 module
async 异步加载脚本,加载完成后立即执行(仅适用于外部脚本)
defer 延迟执行脚本,在文档解析完成后、DOMContentLoaded 事件前执行(仅适用于外部脚本)
crossorigin 设置跨域请求的 CORS 配置
integrity 子资源完整性(SRI)校验,防止脚本被篡改
nomodule 在支持 ES 模块的浏览器中不执行该脚本

4. 加载与执行策略

脚本的加载方式直接影响页面性能,理解 asyncdefer 的区别至关重要。

4.1 默认行为(阻塞)

默认情况下,浏览器在解析到 <script> 标签时会暂停 HTML 解析,先下载并执行脚本,然后再继续解析。这会导致页面渲染被阻塞。

html 复制代码
<!-- 会阻塞页面解析 -->
<script src="js/app.js"></script>

4.2 defer(延迟执行)

defer 属性让脚本在后台下载,同时不阻塞 HTML 解析。脚本会在文档解析完成后按顺序执行。

html 复制代码
<script defer src="js/app.js"></script>

4.3 async(异步执行)

async 属性让脚本在后台下载,下载完成后立即执行,不保证执行顺序,也不等待 HTML 解析完成。

html 复制代码
<script async src="js/analytics.js"></script>

4.4 对比总结

属性 下载时机 执行时机 执行顺序
解析到即下载 下载完立即执行(阻塞解析) 按文档顺序
defer 解析时后台下载 文档解析完成后 按文档顺序
async 解析时后台下载 下载完立即执行 不保证顺序

5. 模块脚本

使用 type="module" 可以将脚本作为 ES 模块加载,支持 importexport 语法。

html 复制代码
<script type="module">
  import { greet } from "./utils.js";
  greet("World");
</script>

模块脚本默认启用严格模式 ,并且具有延迟执行 的特性,即使不加 defer 也会在文档解析完成后执行。

6. 放置位置建议

6.1 传统做法:放在 <body> 末尾

将脚本放在 <body> 结束标签之前,可以确保 DOM 已解析完成,避免操作不存在的元素。

html 复制代码
<body>
  <!-- 页面内容 -->
  <script src="js/app.js"></script>
</body>

6.2 现代做法:放在 <head> 中配合 defer

将脚本放在 <head> 中并添加 defer 属性,既不影响解析,又能提前开始下载。

html 复制代码
<head>
  <script defer src="js/app.js"></script>
</head>

7. 常见问题与最佳实践

7.1 脚本报错:找不到元素

如果脚本在 DOM 解析完成前执行,可能找不到目标元素。解决方案:

  • 将脚本放在 <body> 末尾;
  • 使用 deferasync
  • 监听 DOMContentLoaded 事件。
html 复制代码
<script>
  document.addEventListener("DOMContentLoaded", function () {
    const btn = document.getElementById("btn");
    btn.addEventListener("click", handleClick);
  });
</script>

7.2 使用 SRI 增强安全性

通过 integrity 属性校验脚本完整性,防止 CDN 脚本被篡改。

html 复制代码
<script
  src="https://cdn.example.com/js/lib.js"
  integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
  crossorigin="anonymous"
></script>

7.3 避免阻塞渲染

对于非关键脚本(如统计代码),使用 asyncdefer,避免阻塞首屏渲染。

8. 总结

<script> 元素是 HTML 与 JavaScript 之间的桥梁。掌握它的基本用法、属性含义以及加载策略,是写出高性能网页的关键一步。在实际开发中,建议:

  • 优先使用外部脚本,便于缓存和维护;
  • 使用 defer 处理依赖 DOM 的脚本;
  • 使用 async 加载独立、非关键的脚本;
  • 使用模块脚本组织复杂的前端逻辑。

希望本文能帮助你更好地理解和使用 <script> 元素,写出更高效、更可靠的网页。

相关推荐
weixin_493503675 小时前
Vue3 前端生成 PDF:会员证书与活动签到表的三种打印方案与踩坑记录
前端·pdf·状态模式
尾善爱看海8 小时前
前端算法与手写题集
前端·算法
徐小夕8 小时前
JitWord 4.0 万字分享:从协同工具到AI Word操作系统,聊聊3年产品创业史
前端·vue.js·后端
萧鼎10 小时前
Python 高性能Web框架神器 FastAPI:自动生成API文、基于Pydant、异步请求处理全搞定
前端·python·fastapi
IT_陈寒10 小时前
Redis误用keys命令把生产环境搞崩了,血的教训
前端·人工智能·后端
计算机魔术师11 小时前
5000亿估值冲刺科创板,DeepSeek 为何急着上市?
前端
我血条子呢11 小时前
前端解析word方案
前端·word
kyriewen11 小时前
我用 AI 写完一个需求后才发现,最难的不是 prompt,而是验收
前端·程序员·ai编程
申行11 小时前
Vue 3 + DYMO Connect Framework 实战:从标签模板到打印服务的完整实现
前端