上一篇
html引入js.
- 行业动态
- 2025-05-03
- 3042
HTML引入JS可通过标签实现,支持内联或外链方式,建议置于前并添加async/defer属性优化
HTML引入JavaScript的常见方式
内联脚本(直接在HTML中编写JS代码)
将JavaScript代码直接放置在<script>
标签内,适用于少量逻辑或快速测试。
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8">内联脚本示例</title> </head> <body> <script> // 直接在HTML中编写JS代码 alert("欢迎访问我的网站!"); </script> </body> </html>
特点:
- 代码与HTML混合,不易维护
- 适合临时性、少量的脚本
- 所有脚本默认同步执行(阻塞渲染)
外部脚本(链接外部JS文件)
通过<script src="路径">
引入外部JS文件,推荐用于分离逻辑与结构。
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8">外部脚本示例</title> <script src="main.js"></script> <!-引入外部JS文件 --> </head> <body> <h1>外部脚本演示</h1> </body> </html>
特点:
- 代码复用性强,易于维护
- 浏览器会缓存外部文件,提升性能
- 默认阻塞页面渲染(可通过
async
/defer
优化)
异步加载脚本(async
属性)
添加async
属性后,脚本异步加载,不阻塞页面渲染。
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8">异步脚本示例</title> <script src="main.js" async></script> </head> <body> <h1>异步脚本演示</h1> </body> </html>
特点:
- 脚本并行下载,尽快执行
- 执行顺序不确定(可能打乱依赖关系)
- 适合无依赖的独立脚本(如第三方统计代码)
延迟加载脚本(defer
属性)
添加defer
属性后,脚本延迟到DOM完全加载后执行,但依然并行下载。
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8">延迟脚本示例</title> <script src="main.js" defer></script> </head> <body> <h1>延迟脚本演示</h1> </body> </html>
特点:
- 保证脚本按顺序执行(多个
defer
脚本按顺序执行) - 不阻塞页面渲染,提升首屏速度
- 适合需要操作DOM的脚本(如事件绑定)
ES6模块化导入(<script type="module">
)
使用type="module"
引入模块化JS文件,支持import/export
语法。
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8">模块化脚本示例</title> <script type="module" src="main.js"></script> </head> <body> <h1>模块化脚本演示</h1> </body> </html>
特点:
- 天然支持异步加载(浏览器自动处理依赖)
- 需通过HTTPS或本地环境加载(浏览器安全限制)
- 适合现代化前端工程(如Webpack打包)
关键属性对比表
属性/方式 | 执行时机 | 是否阻塞渲染 | 脚本加载顺序 | 适用场景 |
---|---|---|---|---|
无属性 | 立即执行(同步) | 是 | 按顺序执行 | 简单逻辑、必须提前执行的代码 |
async | 下载完成立即执行 | 否 | 不确定顺序 | 无依赖的第三方脚本(如广告、统计) |
defer | DOM加载完成后执行 | 否 | 按顺序执行 | 需要操作DOM的脚本 |
type="module" | 按需加载(异步) | 否 | 按需解析依赖 | 现代化模块化开发 |
常见问题与解决方案
脚本加载失败如何处理?
- 现象:网络错误或路径错误导致脚本未加载。
- 解决方案:
- 使用
<script>
的onerror
事件监听加载失败:<script src="main.js"></script> <script> document.querySelector('script[src="main.js"]').onerror = function() { alert('主脚本加载失败!'); }; </script>
- 提供备用方案(如本地备份文件):
<script src="https://cdn.example.com/main.js"></script> <script src="local-fallback.js"></script>
- 使用
如何控制脚本执行顺序?
- 现象:多个脚本存在依赖关系(如
scriptB
依赖scriptA
)。 - 解决方案:
- 同步脚本:按HTML中的顺序排列:
<script src="scriptA.js"></script> <script src="scriptB.js"></script>
- 异步/延迟脚本:使用
defer
保证顺序:<script src="scriptA.js" defer></script> <script src="scriptB.js" defer></script>
- 模块化脚本:通过
import
显式声明依赖:// main.js import { funcA } from './scriptA.js'; funcA();
- 同步脚本:按HTML中的顺序排列:
相关问题与解答
问题1:为什么建议将外部脚本放在<body>
标签末尾?
- 解答:
- 避免阻塞页面渲染:脚本默认同步执行,放在
<head>
或<body>
顶部会导致浏览器等待脚本加载完成再渲染页面。 - 提升首屏速度:将脚本放在
<body>
末尾可优先渲染页面内容,改善用户体验。 - 例外情况:若脚本使用
defer
或async
,可放在<head>
中并行加载。
- 避免阻塞页面渲染:脚本默认同步执行,放在
问题2:如何判断当前浏览器是否支持<script type="module">
?
- 解答:
- 方法1:检测
<script>
标签的typeof
属性:const isModuleSupported = 'module' in document.createElement('script'); console.log(isModuleSupported); // true/false
- 方法2:尝试动态创建模块脚本并捕获错误:
function checkModuleSupport() { return new Promise((resolve) => { const script = document.createElement('script'); script.type = 'module'; script.src = URL.createObjectURL(new Blob([`import as m from './test.js'; resolve(m);`], { type: 'application/javascript' })); document.head.appendChild(script); script.onload = () => resolve(true); script.onerror = () => resolve(false); }); } checkModuleSupport().then(console.log); // true/false
- 方法1:检测