URL、History 与本地存储
可分享、可恢复的筛选条件应进入 URL;临时界面偏好可以进入 localStorage。两者都可能被用户修改,读取后仍要校验。
js
const params = new URLSearchParams(location.search);
const page = Math.max(1, Number(params.get('page')) || 1);
function setPage(next) {
const nextParams = new URLSearchParams(location.search);
nextParams.set('page', String(next));
history.pushState({ page: next }, '', `?${nextParams}`);
}pushState 改变地址和历史记录,但不会自动触发页面加载;监听 popstate 才能在后退前进时同步界面。
练习
实现一个过滤器:刷新和复制 URL 后仍能恢复筛选值;无效页码回退到 1,且后退按钮可以恢复上一次筛选。
核心机制与实现
浏览器平台由解析、事件循环、渲染、存储、权限和可观测 API 组成。把任务拆成宏任务、微任务、样式计算和绘制,才能解释顺序。
围绕“URL、History 与本地存储”先写出输入 → 中间状态 → 可观察结果,再实现最小闭环。不要把事件监听、异步请求、DOM 读取或 store 写入混在一个函数里;每个副作用都要有创建、完成、取消和清理路径。
js
console.log('script')
queueMicrotask(() => console.log('microtask'))
requestAnimationFrame(() => console.log('paint callback'))
setTimeout(() => console.log('task'), 0)逐步运行:先只验证成功路径,再改变一个输入;记录时间顺序、对象身份、错误类型和最终可见状态。若环境不支持某个浏览器 API,要把静态协议验证和真实浏览器验证分开记录。
失败边界与变体
- 输入为空、重复、过期或非法时,不应静默覆盖有效状态。
- 组件卸载、路由离开、标签页关闭或请求取消时,资源必须停止写入。
- 跨文档、Shadow DOM、Worker、SSR 或多标签页会改变可见边界,不能沿用单页面直觉。
- 需要持久化时记录 schema 版本和迁移失败策略;需要全局状态时先证明局部状态不足。
可运行实验与练习
在真实浏览器记录输出顺序、布局读取和长任务;改变 DOM、网络和定时器,解释哪些工作阻塞输入与绘制。
练习要求:实现一个最小版本,补一个失败测试,再给出一个替代方案及其适用条件。答案应包括实际输入序列、观察结果、修复原因和未覆盖的浏览器差异。