0

0

HTML中的脚本标签怎么用? script标签使用详解

煙雲

煙雲

发布时间:2025-07-29 13:15:02

|

1083人浏览过

|

来源于php中文网

原创

<script>标签用于嵌入或引用javascript,实现网页交互与动态功能;2. 内联脚本将代码直接写在标签内,适合小量独有代码,但不利于维护;3. 外部脚本通过src属性引入js文件,提升复用性、可维护性并支持缓存;4. defer使脚本在html解析完成后按顺序执行,不阻塞渲染,适用于依赖dom且有依赖关系的脚本;5. async使脚本下载不阻塞解析,但下载完成后立即执行,不保证顺序,适用于独立第三方脚本;6. 推荐将脚本放在</body>前以避免阻塞页面显示,提升用户体验;7. type="module"支持原生es模块,具备默认defer行为、严格模式和私有作用域,实现模块化开发;8. nomodule与type="module"配合使用,为不支持模块的浏览器提供降级脚本,实现渐进增强。因此,合理使用<script>标签的不同属性和位置策略,能有效优化页面性能与代码结构,完整实现现代前端开发的最佳实践。

HTML中的脚本标签怎么用? script标签使用详解

在HTML中,<script>标签是用来嵌入或引用客户端脚本(绝大多数情况下是JavaScript)的。它的核心作用就是让你的网页动起来,实现各种交互、数据处理和动态内容展示。你可以用它来直接写一段JS代码,也可以链接到一个外部的JS文件,这在现代网页开发中简直是不可或缺的。

HTML中的脚本标签怎么用? script标签使用详解

解决方案

使用<script>标签的基本方式有两种:内联脚本和外部脚本。

1. 内联脚本: 直接将JavaScript代码写在<script></script>标签之间。

HTML中的脚本标签怎么用? script标签使用详解
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>内联脚本示例</title>
</head>
<body>
    <h1>欢迎来到我的页面</h1>
    <button onclick="showAlert()">点我</button>

    <script>
        // 这是一段内联的JavaScript代码
        function showAlert() {
            alert('你点击了按钮!');
            console.log('按钮被点击了。');
        }
    </script>
</body>
</html>

这种方式适合代码量较小、特定页面独有的脚本。它的优点是请求少,但缺点也很明显:代码复用性差,维护困难,并且混合了HTML和JS,不利于内容与行为分离。

立即学习前端免费学习笔记(深入)”;

2. 外部脚本: 通过src属性链接到一个外部的JavaScript文件。这是更推荐的做法,特别是对于大型项目或需要复用的脚本。

HTML中的脚本标签怎么用? script标签使用详解
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>外部脚本示例</title>
</head>
<body>
    <h1>欢迎来到我的页面</h1>
    <button id="myButton">点我</button>

    <!-- 引用外部脚本文件 -->
    <script src="scripts/main.js"></script>
</body>
</html>

对应的scripts/main.js文件内容可能如下:

// scripts/main.js
document.addEventListener('DOMContentLoaded', function() {
    const button = document.getElementById('myButton');
    if (button) {
        button.addEventListener('click', function() {
            alert('你点击了外部脚本控制的按钮!');
            console.log('外部脚本执行了。');
        });
    }
});

这种方式的好处是显而易见的:代码组织更清晰,易于维护和复用,而且浏览器可以缓存外部JS文件,提高加载速度。

除了src属性,<script>标签还有几个非常重要的属性,它们直接影响脚本的加载和执行行为:

  • defer: 当你给<script>标签加上defer属性时,脚本会在HTML文档解析完成后才执行,但会在DOMContentLoaded事件触发之前。关键是,它不会阻塞HTML的解析,而且脚本会按照它们在文档中出现的顺序执行。这对于那些依赖DOM但又不想阻塞页面渲染的脚本非常有用。
  • async: 带有async属性的脚本也是异步加载的,不会阻塞HTML解析。但与defer不同的是,async脚本一旦下载完成就会立即执行,不保证执行顺序。这非常适合那些独立于DOM结构、不依赖其他脚本的第三方脚本(比如统计代码)。
  • type: 默认是text/javascript,现在通常可以省略,因为JavaScript是默认的脚本语言。不过,如果你想使用ES模块,就需要设置为type="module"
  • nomodule: 这个属性通常与type="module"配合使用。如果浏览器支持ES模块(即支持type="module"),它就会忽略带有nomodule属性的脚本。反之,如果浏览器不支持ES模块,它就会执行带有nomodule属性的脚本,这提供了一种优雅的降级方案。

为什么脚本标签的位置很重要?——头部与主体放置的性能考量

脚本标签在HTML文档中的位置,老实说,这不仅仅是编码习惯的问题,它直接关系到你网页的加载性能和用户体验。早些年,大家习惯把所有<script>标签都放在<head>里,觉得这样能让脚本尽早加载。但很快就发现问题了:当浏览器遇到<script>标签时,它会暂停HTML的解析,转而去下载并执行这个脚本。如果脚本文件很大,或者网络状况不佳,整个页面就会在那里“卡”住,用户看到的就是一片空白,直到脚本加载执行完毕。这体验简直是灾难性的。

所以,一个非常普遍且推荐的做法是把<script>标签(特别是那些操作DOM的脚本)放在<body>标签的闭合标签</body>之前。这样做的好处是,浏览器可以先解析并渲染完HTML内容,用户能尽快看到页面的骨架,然后再去加载和执行脚本,这样页面的“感知速度”就大大提升了。用户至少能看到东西,而不是一片白屏。

当然,这种“放到</body>前”的策略也不是万能的。有些时候,脚本确实需要在页面渲染前就执行,比如一些页面级别的配置脚本。这时候,deferasync属性就成了救星。它们允许你在<head>中放置脚本,同时又避免了阻塞渲染,这是一种更现代、更灵活的解决方案。在我看来,理解这些细微的差异,并根据脚本的实际作用选择合适的位置和属性,是前端性能优化的一个基本功。

script标签的defer和async属性到底有何区别?——深入理解异步加载

deferasync这两个属性,虽然都是为了解决脚本阻塞页面渲染的问题,但它们的工作机制和适用场景其实大相径庭。简单来说,它们都让脚本的下载变得非阻塞,但执行时机和顺序却完全不同。

  • defer:你可以把defer想象成一个“推迟执行”的开关。当浏览器看到带有defer属性的脚本时,它会立即开始下载这个脚本,但不会暂停HTML的解析。脚本的执行会被推迟到HTML文档解析完毕之后,但在DOMContentLoaded事件触发之前。更重要的是,如果页面上有多个带有defer的脚本,它们会按照在HTML中出现的顺序依次执行。这就像排队一样,先到先服务。这对于那些需要操作DOM,并且脚本之间存在依赖关系的场景非常理想。比如,你有一个主脚本依赖于一个库脚本,如果它们都带有defer,那么库脚本会先执行,然后才是你的主脚本。

    Amazon Nova
    Amazon Nova

    亚马逊云科技(AWS)推出的一系列生成式AI基础模型

    下载
    <head>
        <script defer src="lib.js"></script>
        <script defer src="main.js"></script>
    </head>

    在这个例子中,lib.js会保证在main.js之前执行。

  • async:而async则更像是一个“自由奔放”的模式。同样,浏览器会异步下载带有async属性的脚本,不会阻塞HTML解析。但与defer不同的是,一旦脚本下载完成,它就会立即执行,不等待HTML解析完成,也不保证多个async脚本的执行顺序。哪个脚本先下载完,哪个就先执行。这就像一场赛跑,谁先冲过终点线谁就赢。这种行为非常适合那些独立性强、不依赖DOM也不被其他脚本依赖的脚本,比如第三方统计代码、广告脚本等。它们不关心执行顺序,只希望尽快加载并运行。

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

    在这里,analytics.jsads.js哪个先执行是无法确定的,取决于它们的下载速度。

在我看来,选择defer还是async,关键在于你的脚本是否有序依赖,以及是否需要操作完整的DOM。如果脚本之间有依赖,或者需要等待DOM结构就绪,defer通常是更好的选择。如果脚本是完全独立的,并且越快执行越好,那么async就能提供最大的性能优势。理解这一点,能帮助你做出更明智的性能优化决策。

除了JavaScript,script标签还能做什么?——MIME类型与模块化脚本

虽然我们日常开发中几乎都用<script>标签来承载JavaScript代码,但从技术上讲,它并不局限于此。type属性就是用来指定脚本内容的MIME类型。理论上,你可以指定任何脚本语言,比如早期的VBScript,或者更小众的语言,但实际上,浏览器对这些类型的支持非常有限,或者说,现在几乎只有JavaScript一种通用且被广泛支持的客户端脚本语言。所以,type="text/javascript"现在通常可以省略,因为它是默认值。

然而,type属性在现代前端开发中又重新焕发了生机,那就是通过type="module"来引入ES模块(ECMAScript Modules)。这绝对是JavaScript发展史上的一个里程碑,它为前端带来了原生的模块化能力,告别了过去依赖CommonJS或AMD等模块规范的时代。

当一个<script>标签被设置为type="module"时:

  1. 模块化加载:它会按照ES模块的规范来解析和执行。这意味着你可以在模块中使用importexport语句来组织和共享代码,就像你在Node.js或使用Webpack等打包工具时那样。
  2. 默认defer行为:带有type="module"的脚本默认就具备了defer的特性,即异步加载且不阻塞HTML解析,并在DOM解析完成后按顺序执行。你不需要再显式地添加defer属性。
  3. 严格模式:ES模块默认就在严格模式下运行,这有助于写出更健壮、更少错误的代码。
  4. 作用域:模块内部的变量和函数默认是私有的,不会污染全局作用域,只有通过export导出的内容才能被其他模块import
<script type="module" src="modules/app.js"></script>

对应的modules/app.js可能长这样:

// modules/utils.js
export function greet(name) {
    return `Hello, ${name}!`;
}

// modules/app.js
import { greet } from './utils.js'; // 导入模块

document.addEventListener('DOMContentLoaded', () => {
    const message = greet('World');
    console.log(message);
    document.body.innerHTML += `<h1>${message}</h1>`;
});

type="module"搭配使用的还有nomodule属性。如果你的用户群体中还有一些老旧浏览器不支持ES模块,你可以提供一个带有nomodule属性的脚本作为回退方案。

<script type="module" src="modern-app.js"></script>
<script nomodule src="legacy-app.js"></script>

支持ES模块的浏览器会加载并执行modern-app.js,同时忽略legacy-app.js。而那些不支持ES模块的浏览器则会忽略modern-app.js,转而加载并执行legacy-app.js。这种方式提供了一种非常优雅的渐进增强策略。

在我看来,type="module"是前端工程化发展的一个重要标志,它让浏览器原生支持了模块化,极大地简化了前端项目的结构和依赖管理。虽然在实际项目中,我们可能依然会使用Webpack、Vite等打包工具来处理模块、优化代码,但理解原生ES模块的工作原理,无疑是理解现代前端开发基石的关键。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
js正则表达式
js正则表达式

php中文网为大家提供各种js正则表达式语法大全以及各种js正则表达式使用的方法,还有更多js正则表达式的相关文章、相关下载、相关课程,供大家免费下载体验。

531

2023.06.20

js获取当前时间
js获取当前时间

JS全称JavaScript,是一种具有函数优先的轻量级,解释型或即时编译型的编程语言;它是一种属于网络的高级脚本语言,主要用于Web,常用来为网页添加各式各样的动态功能。js怎么获取当前时间呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

576

2023.07.28

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

761

2023.08.03

js是什么意思
js是什么意思

JS是JavaScript的缩写,它是一种广泛应用于网页开发的脚本语言。JavaScript是一种解释性的、基于对象和事件驱动的编程语言,通常用于为网页增加交互性和动态性。它可以在网页上实现复杂的功能和效果,如表单验证、页面元素操作、动画效果、数据交互等。

6281

2023.08.17

js删除节点的方法
js删除节点的方法

js删除节点的方法有:1、removeChild()方法,用于从父节点中移除指定的子节点,它需要两个参数,第一个参数是要删除的子节点,第二个参数是父节点;2、parentNode.removeChild()方法,可以直接通过父节点调用来删除子节点;3、remove()方法,可以直接删除节点,而无需指定父节点;4、innerHTML属性,用于删除节点的内容。

493

2023.09.01

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

221

2023.09.04

Js中concat和push的区别
Js中concat和push的区别

Js中concat和push的区别:1、concat用于将两个或多个数组合并成一个新数组,并返回这个新数组,而push用于向数组的末尾添加一个或多个元素,并返回修改后的数组的新长度;2、concat不会修改原始数组,是创建新的数组,而push会修改原数组,将新元素添加到原数组的末尾等等。本专题为大家提供concat和push相关的文章、下载、课程内容,供大家免费下载体验。

240

2023.09.14

js截取字符串的方法介绍
js截取字符串的方法介绍

JavaScript字符串截取方法,包括substring、slice、substr、charAt和split方法。这些方法可以根据具体需求,灵活地截取字符串的不同部分。在实际开发中,根据具体情况选择合适的方法进行字符串截取,能够提高代码的效率和可读性 。

303

2023.09.21

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

49

2026.03.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Bootstrap 5教程
Bootstrap 5教程

共46课时 | 3.6万人学习

AngularJS教程
AngularJS教程

共24课时 | 4.2万人学习

CSS教程
CSS教程

共754课时 | 43.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号