<script>-客户端脚本
<script>
标签是 HTML 中用于嵌入或引用客户端脚本的核心元素,通常用于实现动态交互、数据操作或第三方功能集成。它支持多种属性和加载方式,直接影响脚本的执行时机和行为。
<script>
标签的基本语法
<script>
标签的常规写法分为两种:内联脚本和外部脚本。内联脚本直接将代码写在标签内,而外部脚本通过 src
属性引入外部文件。
<!-- 内联脚本示例 -->
<script>
console.log('内联脚本执行');
</script>
<!-- 外部脚本示例 -->
<script src="app.js"></script>
未指定 type
属性时,默认值为 text/javascript
。现代开发中通常省略 type
,因为 JavaScript 已是默认脚本语言。
关键属性解析
src
属性
用于引用外部脚本文件,可以是绝对路径或相对路径。例如:
<script src="https://example.com/library.js"></script>
<script src="/local/path/app.js"></script>
async
与 defer
控制脚本的加载和执行时机:
async
:异步加载,下载完成后立即执行,不保证顺序。<script async src="script1.js"></script> <script async src="script2.js"></script> <!-- script2.js 可能先于 script1.js 执行 -->
defer
:延迟到文档解析完成后按顺序执行。<script defer src="vendor.js"></script> <script defer src="app.js"></script> <!-- 保证 vendor.js 在 app.js 前执行 -->
type
的特殊值
除常规的 MIME 类型外,还可使用模块化脚本:
<script type="module">
import { utils } from './utils.js';
console.log(utils.version);
</script>
脚本加载策略
阻塞渲染问题
默认情况下,浏览器解析到 <script>
时会暂停 HTML 解析,立即执行脚本。将脚本放在 <body>
末尾可减少影响:
<body>
<!-- 页面内容 -->
<script src="app.js"></script>
</body>
动态加载脚本
通过 DOM API 动态插入脚本:
const script = document.createElement('script');
script.src = 'dynamic.js';
document.head.appendChild(script);
实际应用场景
数据埋点
异步加载统计脚本以避免影响主线程:
<script async src="https://analytics.example.com/tracker.js"></script>
第三方库集成
使用 defer
确保依赖顺序:
<script defer src="jquery.min.js"></script>
<script defer src="plugin-depends-on-jquery.js"></script>
性能优化实践
- 代码拆分:按需加载非关键脚本
if (userNeedsFeature) { import('./heavy-module.js').then(module => { module.init(); }); }
- Intersection Observer 懒加载:
const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { const script = document.createElement('script'); script.src = entry.target.dataset.src; document.body.appendChild(script); observer.unobserve(entry.target); } }); }); observer.observe(document.querySelector('[data-src]'));
安全注意事项
内容安全策略 (CSP)
通过 HTTP 头限制脚本来源:
Content-Security-Policy: script-src 'self' https://trusted.cdn.com
防止 XSS
避免拼接 HTML 插入脚本:
// 危险示例
document.write(`<script>alert("${userInput}")</script>`);
// 安全做法
const el = document.createElement('div');
el.textContent = userInput;
document.body.appendChild(el);
兼容性与现代实践
传统浏览器降级
使用 nomodule
为不支持 ES6 的浏览器提供回退:
<script type="module" src="modern.js"></script>
<script nomodule src="legacy.js"></script>
预加载关键资源
通过 <link rel="preload">
提前加载:
<link rel="preload" href="critical.js" as="script">
调试技巧
源代码映射
通过 sourcemap
调试压缩代码:
<script src="app.min.js"></script>
<!-- 同时存在 app.min.js.map -->
错误捕获
全局监听脚本错误:
window.addEventListener('error', (e) => {
console.error('脚本加载失败:', e.filename);
});
与其他技术的协作
与 Web Workers 配合
将计算密集型任务移出主线程:
// main.js
const worker = new Worker('worker.js');
worker.postMessage(data);
// worker.js
self.onmessage = (e) => {
const result = heavyComputation(e.data);
self.postMessage(result);
};
服务器端渲染 (SSR) 注意事项
避免重复执行客户端脚本:
<script data-ssr="true">
window.APP_DATA = JSON.parse('{{serverData|escapejs}}');
</script>
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益,请来信告知我们删除。邮箱:cc@cccx.cn
上一篇:<slot>-Web组件插槽
下一篇:<iframe>-内联框架