<script> 标签
<script> 标签用于嵌入或引用 JavaScript 代码。它可以在 HTML 文档中定义客户端脚本,为网页添加交互功能。
概述
<script> 标签用于定义或引用客户端脚本,通常是 JavaScript。它可以嵌入内联脚本或链接到外部脚本文件。
语法
内联脚本
html
<script>
// JavaScript 代码
</script>外部脚本
html
<script src="script.js"></script>常用属性
src 属性
指定外部脚本文件的 URL:
html
<script src="script.js"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js"></script>type 属性
指定脚本的 MIME 类型(在 HTML5 中可选):
html
<script type="text/javascript">
// JavaScript 代码
</script>async 属性
异步执行脚本(不保证执行顺序):
html
<script src="script1.js" async></script>
<script src="script2.js" async></script>defer 属性
延迟执行脚本(在文档解析完成后执行,保持顺序):
html
<script src="script1.js" defer></script>
<script src="script2.js" defer></script>crossorigin 属性
设置 CORS 请求的模式:
html
<script src="https://cdn.example.com/script.js" crossorigin="anonymous"></script>integrity 属性
提供资源的完整性哈希值:
html
<script src="https://cdn.example.com/script.js"
integrity="sha384-..."
crossorigin="anonymous"></script>基本用法
内联脚本
html
<!DOCTYPE html>
<html>
<head>
<title>内联脚本示例</title>
</head>
<body>
<button id="myButton">点击我</button>
<script>
document.getElementById('myButton').addEventListener('click', function() {
alert('按钮被点击了!');
});
</script>
</body>
</html>外部脚本
html
<!DOCTYPE html>
<html>
<head>
<title>外部脚本示例</title>
</head>
<body>
<button id="myButton">点击我</button>
<!-- 引用外部脚本文件 -->
<script src="script.js"></script>
</body>
</html>对应的 script.js 文件:
javascript
document.getElementById('myButton').addEventListener('click', function() {
alert('按钮被点击了!');
});脚本加载策略
默认加载(同步阻塞)
html
<!-- 会阻塞 HTML 解析,直到脚本加载并执行完成 -->
<script src="script.js"></script>异步加载(async)
html
<!-- 异步加载脚本,不阻塞 HTML 解析 -->
<!-- 不保证脚本执行顺序 -->
<script src="script1.js" async></script>
<script src="script2.js" async></script>延迟执行(defer)
html
<!-- 延迟执行脚本,在文档解析完成后按顺序执行 -->
<script src="script1.js" defer></script>
<script src="script2.js" defer></script>位置和执行时机
在 <head> 中
html
<!DOCTYPE html>
<html>
<head>
<title>脚本在头部</title>
<script src="script.js"></script>
<script>
// 这里的代码会立即执行
console.log('头部脚本执行');
</script>
</head>
<body>
<h1>页面内容</h1>
</body>
</html>在 <body> 底部(推荐)
html
<!DOCTYPE html>
<html>
<head>
<title>脚本在底部</title>
</head>
<body>
<h1>页面内容</h1>
<!-- 在页面内容之后加载脚本 -->
<script src="script.js"></script>
<script>
// DOM 已经加载完成,可以直接操作元素
console.log('底部脚本执行');
</script>
</body>
</html>模块化脚本
ES6 模块
html
<!-- 导入模块 -->
<script type="module" src="main.js"></script>
<!-- 内联模块 -->
<script type="module">
import { add, multiply } from './math.js';
console.log(add(2, 3)); // 5
console.log(multiply(2, 3)); // 6
</script>异步模块
html
<script type="module" async>
import { fetchData } from './api.js';
const data = await fetchData();
console.log(data);
</script>完整示例
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JavaScript 脚本示例</title>
<!-- 关键库同步加载 -->
<script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js"></script>
<!-- 模块化脚本 -->
<script type="module">
// 导入模块
import { initializeApp } from './app.js';
// DOM 加载完成后执行
$(document).ready(function() {
initializeApp();
});
</script>
</head>
<body>
<header>
<h1>网页开发教程</h1>
</header>
<main>
<section>
<h2>交互示例</h2>
<button id="alertButton">显示提示</button>
<button id="toggleButton">切换内容</button>
<div id="toggleContent" style="display: none;">
<p>这是可切换的内容。</p>
</div>
</section>
</main>
<!-- 工具库延迟加载 -->
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js" defer></script>
<!-- 页面特定脚本 -->
<script>
// 简单的交互功能
document.getElementById('alertButton').addEventListener('click', function() {
alert('你好,欢迎学习网页开发!');
});
document.getElementById('toggleButton').addEventListener('click', function() {
const content = document.getElementById('toggleContent');
if (content.style.display === 'none') {
content.style.display = 'block';
this.textContent = '隐藏内容';
} else {
content.style.display = 'none';
this.textContent = '显示内容';
}
});
// 页面加载完成后的初始化
document.addEventListener('DOMContentLoaded', function() {
console.log('页面 DOM 加载完成');
// 发送分析数据
if (typeof gtag !== 'undefined') {
gtag('event', 'page_view');
}
});
</script>
<!-- 非关键分析脚本异步加载 -->
<script src="https://www.google-analytics.com/analytics.js" async></script>
</body>
</html>错误处理
错误事件监听
html
<script>
window.addEventListener('error', function(event) {
console.error('脚本错误:', event.error);
// 发送错误报告到服务器
});
</script>资源加载错误处理
html
<script>
// 监听脚本加载错误
document.addEventListener('error', function(event) {
if (event.target.tagName === 'SCRIPT') {
console.error('脚本加载失败:', event.target.src);
}
}, true);
</script>安全考虑
内容安全策略 (CSP)
html
<!-- 设置内容安全策略 -->
<meta http-equiv="Content-Security-Policy"
content="script-src 'self' https://apis.google.com; object-src 'none'">子资源完整性 (SRI)
html
<script src="https://cdn.example.com/script.js"
integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
crossorigin="anonymous"></script>避免内联事件处理器
html
<!-- 不推荐 -->
<button onclick="alert('不推荐')">点击</button>
<!-- 推荐 -->
<button id="myButton">点击</button>
<script>
document.getElementById('myButton').addEventListener('click', function() {
alert('推荐');
});
</script>最佳实践
- 脚本位置:将脚本放在
</body>标签之前以提高页面加载速度 - 使用 defer 或 async:对于外部脚本,根据需要使用
defer或async属性 - 模块化:使用 ES6 模块组织代码
- 外部脚本:优先使用外部脚本文件以便缓存和复用
- 压缩代码:在生产环境中压缩 JavaScript 代码
- 错误处理:添加适当的错误处理机制
- 安全措施:使用 CSP 和 SRI 提高安全性
浏览器兼容性
<script> 标签在所有浏览器中都得到支持:
- Chrome
- Firefox
- Safari
- Edge
- Internet Explorer
不同属性的支持情况:
async: IE10+defer: IE10+type="module": 现代浏览器integrity: 现代浏览器
注意事项
<script>标签可以有结束标签</script>- 在内联脚本中避免使用
</script>字符串,可以使用'<\/script>'或将其分开放置 - 外部脚本和内联脚本不能同时存在于同一个
<script>标签中 - 使用
async时脚本执行顺序不保证 - 使用
defer时脚本会在 DOM 解析完成后按顺序执行 - 模块脚本默认具有
defer行为