源本科技 | 码上会

HTML 中添加 JavaScript

2025/12/29
15
0

学习目标

  • 掌握在 HTML 中嵌入 JavaScript 的三种主要方式

  • 理解内联脚本、内部脚本与外部脚本的适用场景

  • 学会使用 asyncdefer 优化脚本加载性能

  • 遵循现代 Web 开发的最佳实践,编写可维护的代码


内联 JavaScript

内联 JavaScript 是指直接在 HTML 元素的事件属性(如 onclickonmouseover)中编写 JavaScript 代码。

示例

<html>
<head></head>
<body>
    <h2>在 HTML 文档中添加 JavaScript</h2>
    <button onclick="alert('按钮被点击了!')">点击这里</button>
</body>
</html>

特点

  • ✅ 适合快速原型或极简单的交互

  • ❌ 混淆结构(HTML)与行为(JS),违反“关注点分离”原则

  • ❌ 无法复用,难以调试和维护

建议:仅用于教学演示,生产环境中应避免使用。


内部 JavaScript

通过 <script> 标签将 JavaScript 代码直接写在 HTML 文件内部。可放置在 <head><body> 中。

放在 <head> 标签内

脚本会在页面内容渲染前加载,适用于初始化逻辑或工具函数。

<html>
<head>
    <script>
        function changeContent() {
            document.getElementById("demo").innerHTML = "内容已更新!";
        }
    </script>
</head>
<body>
    <h3 id="demo" style="color:green;">技术社区</h3>
    <button type="button" onclick="changeContent()">点击这里</button>
</body>
</html>

注意:若脚本操作 DOM 元素,而元素尚未加载,会导致错误。

放在 <body> 标签内

推荐

通常放在 <body> 底部,确保 DOM 已完全加载后再执行脚本。

<html>
<head></head>
<body>
    <h3 id="demo" style="color:green;">技术社区</h3>
    <button type="button" onclick="changeContent()">点击这里</button>

    <script>
        function changeContent() {
            document.getElementById("demo").innerHTML = "内容已更新!";
        }
    </script>
</body>
</html>

最佳实践:对 DOM 操作的脚本,应置于 </body> 之前。


外部 JavaScript

将 JavaScript 代码保存在独立的 .js 文件中,并通过 <script> 标签的 src 属性引入。

HTML 文件:

<html>
<head>
    <script src="script.js"></script>
</head>
<body>
    <h3 id="demo" style="color:green;">技术社区</h3>
    <button type="button" onclick="changeContent()">点击这里</button>
</body>
</html>

script.js 文件内容:

function changeContent() {
    document.getElementById("demo").innerHTML = "内容已更新!";
}

引用路径的三种方式:

类型

示例

当前目录

src="script.js"

子目录路径

src="js/script.js"

根路径

src="/js/script.js"

完整 URL(CDN)

src="https://cdn.example.com/script.js"

外部脚本的优势:

  • 提升页面加载速度:浏览器可缓存 .js 文件

  • 代码结构清晰:HTML 专注结构,JavaScript 专注行为

  • 易于维护与复用:一处修改,多页生效

  • 团队协作友好:前端与逻辑开发可并行


异步与延迟加载

asyncdefer

默认情况下,HTML 解析遇到 <script> 会暂停,直到脚本下载并执行完毕。这可能阻塞页面渲染。为优化性能,可使用以下两个属性:

async 属性(异步加载)

  • 脚本并行下载,不阻塞 HTML 解析

  • 下载完成后立即执行执行顺序不保证

  • 适用于独立脚本(如统计、广告)

<script src="analytics.js" async></script>

defer 属性(延迟执行)

  • 脚本并行下载,但等到 HTML 解析完成后再按顺序执行

  • 适用于依赖完整 DOM 的应用逻辑

<script src="app.js" defer></script>

加载行为对比:

属性

是否阻塞解析

执行时机

顺序保证

适用场景

立即

小型关键脚本

async

下载完立即

❌ 否

独立第三方脚本

defer

DOM 解析完成后

✅ 是

主应用逻辑

推荐:主业务逻辑使用 defer,第三方脚本使用 async


重点总结

  • 内联脚本:简单但不可维护,仅用于演示。

  • 内部脚本:适合小型项目,DOM 操作脚本应放 <body> 底部。

  • 外部脚本:大型项目首选,提升性能与可维护性。

  • defer vs async

    • defer 处理依赖 DOM 的核心逻辑;

    • async 加载独立的第三方脚本。

  • 始终遵循 关注点分离 原则,保持代码整洁。


思考题

  1. 为什么将 <script> 放在 <body> 底部可以避免 “Cannot read property of null” 错误?

  2. 如果一个页面同时引入多个 defer 脚本,它们的执行顺序是否与引入顺序一致?为什么?

  3. 在什么情况下,即使使用了外部脚本,仍可能导致页面加载变慢?如何优化?