您现在的位置是:网站首页 > <script>-客户端脚本文章详情
<script>-客户端脚本
陈川
【
HTML
】
42592人已围观
5390字
<script>
标签是 HTML 中用于嵌入或引用客户端脚本的核心元素,通常用于实现动态交互、数据处理或页面行为控制。它支持多种脚本语言,但现代开发中主要使用 JavaScript。
<script>
标签的基本语法
<script>
标签可以直接在 HTML 文档中嵌入脚本代码,或通过 src
属性引用外部脚本文件。以下是两种常见写法:
<!-- 内联脚本 -->
<script>
console.log("Hello, World!");
</script>
<!-- 外部脚本 -->
<script src="app.js"></script>
标签的 type
属性在 HTML5 中默认为 text/javascript
,通常可省略。早期版本可能需要明确指定:
<script type="text/javascript">
// 传统写法
</script>
脚本的加载行为
默认同步加载
默认情况下,浏览器会同步解析并执行 <script>
标签,这会阻塞 HTML 解析:
<script>
document.write("这段内容会立即输出");
</script>
<p>这段文字会在脚本执行后显示</p>
异步加载模式
通过 async
和 defer
属性可以改变脚本加载行为:
<!-- 异步加载(下载不阻塞HTML解析,下载完成后立即执行) -->
<script async src="analytics.js"></script>
<!-- 延迟执行(下载不阻塞HTML解析,在DOMContentLoaded前执行) -->
<script defer src="ui.js"></script>
两者的区别:
async
脚本无序执行,适合独立模块defer
脚本按文档顺序执行,适合依赖型脚本
动态脚本加载
通过 DOM API 动态创建脚本元素:
const script = document.createElement('script');
script.src = 'dynamic.js';
document.head.appendChild(script);
动态加载的脚本默认具有 async
行为,可以手动改为同步:
script.async = false;
模块化脚本
现代 JavaScript 支持模块系统,通过 type="module"
声明:
<script type="module">
import { utils } from './utils.js';
utils.log('模块已加载');
</script>
模块脚本默认具有 defer
特性,且支持跨域请求(需 CORS 配置):
<script type="module" crossorigin src="https://example.com/module.js"></script>
事件处理
<script>
标签支持加载事件回调:
<script src="big-file.js" onload="init()" onerror="handleError()"></script>
对应的 JavaScript 实现:
const script = document.createElement('script');
script.onload = () => console.log('脚本加载完成');
script.onerror = () => console.error('加载失败');
script.src = 'app.js';
数据块(Data Blocks)
非 JavaScript 内容可以通过自定义类型声明:
<script type="application/json" id="config">
{
"apiUrl": "https://api.example.com",
"timeout": 5000
}
</script>
<script>
const config = JSON.parse(document.getElementById('config').text);
console.log(config.apiUrl); // 输出API地址
</script>
性能优化实践
预加载关键资源
<link rel="preload" href="critical.js" as="script">
代码分割示例
配合现代打包工具实现按需加载:
// 动态导入模块
button.addEventListener('click', async () => {
const module = await import('./dialog.js');
module.open();
});
内联关键脚本
首屏关键脚本可直接内联以减少请求:
<script>
// 内联的初始化代码
(function(){
const theme = localStorage.getItem('theme') || 'light';
document.documentElement.className = theme;
})();
</script>
安全注意事项
内容安全策略(CSP)
通过 HTTP 头限制脚本来源:
Content-Security-Policy: script-src 'self' https://trusted.cdn.com
防止内联脚本注入
避免拼接 HTML 字符串:
// 危险示例
element.innerHTML = `<script>maliciousCode()</script>`;
// 安全方案
const script = document.createElement('script');
script.textContent = 'safeCode()';
element.appendChild(script);
兼容性处理
传统浏览器降级
<script>
// 现代特性检测
if(!window.Promise) {
document.write('<script src="polyfill.js"><\/script>');
}
</script>
noscript 备用方案
<noscript>
<style>.js-content { display: none }</style>
<p>请启用JavaScript以获得完整功能</p>
</noscript>
调试技巧
源码映射配置
<script src="app.min.js" sourcemap="app.min.js.map"></script>
错误追踪示例
window.addEventListener('error', (e) => {
console.error(`脚本错误: ${e.message} @ ${e.filename}:${e.lineno}`);
});
服务端渲染结合
在 Node.js 环境中动态注入脚本:
const serverData = { user: { name: 'Alice' } };
res.send(`
<script>window.__INITIAL_STATE__ = ${JSON.stringify(serverData)}</script>
<script src="client.js"></script>
`);
现代框架中的使用
React 示例
function App() {
useEffect(() => {
const script = document.createElement('script');
script.src = "third-party.js";
document.body.appendChild(script);
return () => script.remove();
}, []);
return <div>内容区</div>;
}
Vue 示例
<template>
<div>
<script v-if="needsScript" src="component-dep.js"></script>
</div>
</template>
<script>
export default {
mounted() {
loadScript('dynamic-dep.js').then(() => {
this.initialize();
});
}
}
</script>
性能监控
测量脚本加载时间:
const script = document.createElement('script');
const start = performance.now();
script.onload = () => {
const loadTime = performance.now() - start;
console.log(`脚本加载耗时: ${loadTime.toFixed(2)}ms`);
};
script.src = 'analytics.js';
document.head.appendChild(script);
缓存控制策略
通过版本号管理缓存:
<script src="app.js?v=20230601"></script>
或使用文件指纹:
<script src="app.3a7b8c9.js"></script>
代码组织模式
IIFE 封装
<script>
(function(global) {
'use strict';
// 私有作用域代码
global.publicAPI = { ... };
})(window);
</script>
命名空间模式
window.MYAPP = window.MYAPP || {};
MYAPP.utils = {
formatDate(date) { /* ... */ }
};
与其它技术的协作
Web Workers 通信
<script>
const worker = new Worker('task.js');
worker.postMessage({ cmd: 'start' });
worker.onmessage = (e) => console.log(e.data);
</script>
Web Components 集成
class MyElement extends HTMLElement {
constructor() {
super();
const script = document.createElement('script');
script.textContent = `console.log('元素已创建')`;
this.appendChild(script);
}
}
customElements.define('my-element', MyElement);
上一篇: <style>-内嵌CSS样式
下一篇: <base>-基准URL设置