localstorage本页修改无法触发storage事件,需劫持setitem/removeitem并派发自定义事件;跨页修改才触发storage事件,且ie8–9除外;document.domain设置会导致storage事件失效。

localStorage 本身不能监听本页修改,只能被其他同源页面“通知”;想监听本页变化,必须自己劫持 setItem 和 removeItem 方法。
storage 事件只在跨页面时触发
你在页面 A 执行 localStorage.setItem('token', 'abc'),页面 B(同源、已打开)能收到 storage 事件,但页面 A 自己收不到——这是浏览器规范行为,不是 bug。Chrome/Firefox/Safari 都如此,IE8–9 是例外(会自触发),但早已淘汰。
- 事件必须注册在
window上(IE8/9 要用document.attachEvent,现在基本不用管) - 事件对象有
event.key、event.oldValue、event.newValue、event.url,可直接取变更信息 - 如果多个标签页都监听了同一 key,每个都会收到,需靠
event.url判断来源,避免重复响应
如何监听本页面的 localStorage 变化
因为原生 storage 事件不响应本页操作,常见做法是包装原生方法:保存原始 setItem,重写它,在调用前派发一个自定义事件(如 ls-change),再执行原逻辑。
- 必须在页面最开始就做劫持,否则中间插入的 set 操作会漏掉
- 注意不要无限递归:重写后的
setItem内部调用的是原始方法,不是自己 - 示例精简版:
const originalSetItem = localStorage.setItem;
localStorage.setItem = function(key, value) {
const event = new CustomEvent('ls-change', {
detail: { key, newValue: value, oldValue: localStorage.getItem(key) }
});
window.dispatchEvent(event);
originalSetItem.apply(this, arguments);
};
之后用 window.addEventListener('ls-change', handler) 即可捕获本页所有 setItem 变更。
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
兼容性坑:document.domain 会让 storage 事件失效
如果你的页面设置了 document.domain = 'example.com'(比如做 iframe 跨子域通信),那么 Chrome(含新版)中 storage 事件将完全不触发——这是已知且未修复的限制,不是代码写错了。
- 此时跨页同步彻底失效,只能退回到轮询或自定义事件 + postMessage 组合方案
- 判断是否受影响:在控制台执行
document.domain !== location.hostname,返回true就大概率中招 - 别试图用
setTimeout补救,事件根本不会进队列
监听指定 key 的变化要自己过滤
原生 storage 事件是全局的,改任意 key 都会触发。实际业务中往往只关心 cart 或 user 这类 key,所以监听函数里必须加判断:
- 推荐封装成工具函数:
onLocalStorageChange('cart', callback),内部统一管理 listener 和 key 匹配逻辑 - 注意
event.newValue === null表示是removeItem操作(不是 undefined) - 不要依赖
event.oldValue在所有浏览器都准确——IE9 下它总是null,得手动读一次再存旧值
真正麻烦的从来不是“怎么写”,而是“什么时候不该信 event.oldValue”和“为什么这个 tab 没反应”——这两点卡住的人最多。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










