浏览器相关 API
DOM 事件、存储、fetch、Worker、Observer 等由浏览器提供的 Web API(非 ECMAScript 核心)。HTML 结构见 标签。
一、DOM 与事件
1. 事件流(捕获 → 目标 → 冒泡)
事件传播分为三个阶段:
- 捕获阶段(capture phase):从
window向下传播到目标元素。 - 目标阶段(target phase):到达目标元素。
- 冒泡阶段(bubble phase):从目标元素向上传播回
window。
默认情况下,事件在冒泡阶段触发。通过 addEventListener 的第三个参数可调整。
2. addEventListener 的 useCapture 与 once
element.addEventListener("click", handler, {
capture: true, // 在捕获阶段触发(默认为 false 冒泡阶段)
once: true, // 触发一次后自动移除监听
});
// 旧版写法:第三个参数为布尔值表示 useCapture
element.addEventListener("click", handler, true);
常用模式:
- 阻止冒泡:
event.stopPropagation() - 阻止默认行为:
event.preventDefault()
3. 事件委托原理与性能优化
原理:利用事件冒泡,在父元素上监听事件,通过 event.target 判断实际触发的子元素。
优点:
- 减少内存占用(无需为每个子元素绑定监听)。
- 动态添加的子元素自动拥有事件响应。
示例:
document.getElementById("list").addEventListener("click", e => {
if (e.target.matches("li.item")) {
console.log("点击了", e.target.textContent);
}
});
4. 自定义事件(CustomEvent)
用于组件通信或解耦逻辑。
// 创建并派发
const event = new CustomEvent("myEvent", { detail: { id: 123 } });
element.dispatchEvent(event);
// 监听
element.addEventListener("myEvent", e => {
console.log(e.detail.id);
});
5. MutationObserver – 监听 DOM 变化
异步监听 DOM 树的变化(属性、子节点、文本等)。
const observer = new MutationObserver(mutationsList => {
for (const mutation of mutationsList) {
if (mutation.type === "childList") {
console.log("子节点变化");
}
}
});
observer.observe(targetNode, {
attributes: true,
childList: true,
subtree: true,
});
// 停止监听
observer.disconnect();
6. IntersectionObserver – 懒加载、无限滚动
异步观察目标元素与视口(或指定祖先元素)的交叉状态。
const observer = new IntersectionObserver(
entries => {
entries.forEach(entry => {
if (entry.isIntersecting) {
// 进入视口,加载图片或更多数据
loadImage(entry.target);
observer.unobserve(entry.target); // 一次加载后停止观察
}
});
},
{ threshold: 0.1 }
);
observer.observe(imgElement);
应用:图片懒加载、无限滚动列表、曝光统计。
7. ResizeObserver – 监听元素尺寸变化
比 window.resize 更精确,可观察任意元素。
const resizeObserver = new ResizeObserver(entries => {
for (let entry of entries) {
console.log(entry.contentRect.width, entry.contentRect.height);
}
});
resizeObserver.observe(someElement);
二、BOM 操作(浏览器对象模型)
1. history 对象 – SPA 路由核心
history.pushState(state, title, url):添加历史记录,不刷新页面。history.replaceState(state, title, url):替换当前历史记录。window.onpopstate:监听浏览器前进/后退。
// 简易 SPA 路由
window.addEventListener("popstate", () => {
const path = location.pathname;
renderView(path);
});
2. navigator – 浏览器与设备信息
常用属性:
navigator.userAgent:用户代理字符串。navigator.language:当前语言。navigator.onLine:是否在线。navigator.geolocation:地理位置。navigator.clipboard:剪贴板 API(见下文)。navigator.serviceWorker:Service Worker 注册。
3. screen – 屏幕信息
screen.width/height:屏幕分辨率。screen.availWidth/availHeight:可用区域(排除任务栏)。screen.colorDepth:色彩深度。
4. location – URL 精细操作
// 获取参数
const urlParams = new URLSearchParams(location.search);
const id = urlParams.get("id");
// 跳转
location.href = "https://example.com";
location.assign("https://example.com");
location.replace("https://example.com"); // 无历史记录
location.reload();
// 获取各部分
location.protocol; // "https:"
location.host; // "example.com:8080"
location.pathname; // "/path"
location.hash; // "#section"
三、Canvas 与 WebGL 基础(简要)
1. Canvas 2D
const canvas = document.getElementById("myCanvas");
const ctx = canvas.getContext("2d");
ctx.fillStyle = "red";
ctx.fillRect(10, 10, 100, 50);
ctx.beginPath();
ctx.arc(200, 75, 40, 0, 2 * Math.PI);
ctx.stroke();
常用:像素处理 getImageData/putImageData、绘制图像 drawImage、动画 requestAnimationFrame。
2. WebGL(基于 OpenGL ES)
用于高性能 3D/2D 图形渲染(如 Three.js 底层)。
const gl = canvas.getContext("webgl");
// 编写着色器、缓冲区等,通常借助 Three.js 等库简化开发。
四、Web 存储
1. localStorage / sessionStorage
- 容量:约 5-10MB。
- 同步 API:
setItem、getItem、removeItem、clear。 - 存储类型:字符串(其他类型需
JSON.stringify/parse)。 - 生命周期:
localStorage永久;sessionStorage为标签页关闭即清除。
监听 storage 事件(仅在同源不同标签页间触发):
window.addEventListener("storage", e => {
console.log(e.key, e.oldValue, e.newValue, e.url);
});
2. IndexedDB – 大型结构化数据存储
异步、事务、索引、支持大量数据。
const request = indexedDB.open("myDB", 1);
request.onsuccess = e => {
const db = e.target.result;
const transaction = db.transaction(["users"], "readwrite");
const store = transaction.objectStore("users");
store.add({ id: 1, name: "Alice" });
};
关键概念:
- 对象存储(类似表)
- 索引(加速查询)
- 游标(遍历数据)
3. Cookies 进阶属性
SameSite:Strict(完全禁止第三方请求携带)、Lax(部分允许)、None(需配合Secure)。Secure:仅 HTTPS 传输。HttpOnly:禁止 JavaScript 访问,防止 XSS 窃取。Max-Age/Expires:过期时间。
document.cookie = "token=abc; Secure; SameSite=Strict; Max-Age=3600";
五、网络请求
1. Fetch 完全指南
// 基本 GET
fetch("/api/data")
.then(res => {
if (!res.ok) throw new Error("HTTP error");
return res.json();
})
.catch(err => console.error(err));
// POST with JSON
fetch("/api/post", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ foo: "bar" }),
});
// 请求/响应拦截(可通过封装或 Proxy 实现)
const originalFetch = window.fetch;
window.fetch = function (...args) {
console.log("Request:", args);
return originalFetch(...args).then(res => {
console.log("Response:", res);
return res;
});
};
// 自定义 AbortSignal(中止请求)
const controller = new AbortController();
fetch("/api/long", { signal: controller.signal });
setTimeout(() => controller.abort(), 1000);
// Stream API 处理大文件(例如逐块读取)
const response = await fetch("/large-file");
const reader = response.body.getReader();
while (true) {
const { done, value } = await reader.read();
if (done) break;
console.log("Received chunk:", value);
}
2. XMLHttpRequest 进阶(进度监控)
const xhr = new XMLHttpRequest();
xhr.open("POST", "/upload");
xhr.upload.onprogress = e => {
console.log(`Uploaded ${e.loaded}/${e.total}`);
};
xhr.onload = () => console.log("Done");
xhr.send(formData);
3. WebSocket – 全双工实时通信
const ws = new WebSocket("wss://example.com/socket");
ws.onopen = () => ws.send("Hello");
ws.onmessage = e => console.log("Received:", e.data);
ws.onerror = err => console.error(err);
ws.onclose = () => console.log("Closed");
// 重连机制示例
function connect() {
const ws = new WebSocket(url);
ws.onclose = () => setTimeout(connect, 1000);
}
4. Server-Sent Events (SSE) – 服务器单向推送
const evtSource = new EventSource("/events");
evtSource.onmessage = e => console.log("Data:", e.data);
evtSource.addEventListener("customEvent", e => {});
六、多线程
1. Web Worker(专用线程)
运行独立于主线程的脚本,用于密集计算。
// worker.js
self.onmessage = e => {
const result = heavyCalculation(e.data);
self.postMessage(result);
};
// main.js
const worker = new Worker("worker.js");
worker.postMessage(input);
worker.onmessage = e => console.log(e.data);
Shared Worker:多标签页共享一个 worker。 Service Worker:代理网络请求,实现离线缓存(PWA)、消息推送。
2. Service Worker(离线缓存 + 消息推送)
// 注册
navigator.serviceWorker.register("/sw.js");
// sw.js 中拦截 fetch 事件,返回缓存或网络响应
self.addEventListener("fetch", event => {
event.respondWith(
caches.match(event.request).then(resp => resp || fetch(event.request))
);
});
3. SharedArrayBuffer 与原子操作(Atomics)
用于多个 Worker 或主线程之间共享内存(需跨域隔离上下文)。
// 主线程
const sab = new SharedArrayBuffer(1024);
const int32 = new Int32Array(sab);
worker.postMessage(sab);
// Worker 中
Atomics.add(int32, 0, 1);
Atomics.notify(int32, 0, 1);
七、剪贴板 API
异步读写剪贴板(需用户授权):
// 写入文本
await navigator.clipboard.writeText("Hello World");
// 读取文本
const text = await navigator.clipboard.readText();
// 写入图片(ClipboardItem)
const imgBlob = await fetch("image.png").then(r => r.blob());
await navigator.clipboard.write([
new ClipboardItem({ [imgBlob.type]: imgBlob }),
]);
八、全屏 API 与页面可见性
1. 全屏 API
// 进入全屏
document.documentElement.requestFullscreen();
// 退出全屏
document.exitFullscreen();
// 监听变化
document.addEventListener("fullscreenchange", () => {
console.log(document.fullscreenElement);
});
2. 页面可见性 API
document.addEventListener("visibilitychange", () => {
if (document.hidden) {
console.log("页面隐藏,暂停动画或轮询");
} else {
console.log("页面可见,恢复");
}
});
总结
| 类别 | 核心 API / 概念 |
|---|---|
| DOM 事件 | 事件流(捕获/冒泡)、委托、CustomEvent、MutationObserver、IntersectionObserver、ResizeObserver |
| BOM | history (SPA)、navigator、screen、location 精细操作 |
| 图形 | Canvas 2D、WebGL (Three.js 等) |
| 存储 | localStorage/sessionStorage、IndexedDB、Cookies (SameSite/Secure/HttpOnly) |
| 网络请求 | fetch (拦截、中止、流)、XHR (进度监听)、WebSocket、SSE |
| 多线程 | Web Worker、Shared Worker、Service Worker、SharedArrayBuffer + Atomics |
| 剪贴板 | navigator.clipboard (readText/writeText) |
| 其他 | 全屏 API、页面可见性 API |
生产项目须关注 API 兼容性(查 MDN 兼容性表)与 HTTPS 等安全要求(如 Service Worker)。
参考文献
以下链接在编写时均可正常访问:
| 资料 | 说明 |
|---|---|
| MDN:Document Object Model | DOM |
| MDN:事件 | 事件对象 |
| MDN:fetch | 网络请求 |
| MDN:Web Workers | Worker |
| MDN:Intersection Observer | 交叉观察器 |
| MDN:Storage | localStorage 等 |
相关文章
错误处理与调试
结构化错误类型、try/catch 与全局未捕获处理是健壮应用的基础。
性能优化
防抖/节流、渲染与内存、资源预加载及引擎行为是前端性能的主要抓手。相关 CSS 见 视觉效果、Head 资源提示。
模块化与工程化
ESM、CommonJS 与打包工具(Tree Shaking、代码分割)是前端工程化的基础。入门见 JavaScript 基础 · 模块。
执行模型与作用域
执行上下文与词法作用域决定变量在何处可访问、闭包如何形成,以及 var / let / const 的差异。语言概览见 JavaScript 基础。
数据结构与集合增强
Map / Set、WeakMap / WeakSet、数组高阶方法、TypedArray 与 Symbol 等扩展了内置数据结构能力。见 语言基础。
JavaScript 基础
JavaScript(ECMAScript)是 Web 页面与 Node.js 等运行时的脚本语言:在浏览器中操作 DOM、发起网络请求;在服务端处理 I/O。语法与 HTML、CSS 配合构成前端技术栈。