消息订阅与发布
// 先保存一份原来的方法
let originalSetItem = localStorage.setItem
// 重写setItem方法
localStorage.setItem = function (key, value) {
// 创建event
const event = new Event('storageChange')
// 把key和value 加到 event中(为了监听的时候获取到)
event.key = key
event.value = value
// 派发(派发了才能监听到)
document.dispatchEvent(event)
// 调用原来的setItem来设置值
originalSetItem.apply(this, arguments)
}
// 监听!我们的目的
document.addEventListener('storageChange', function (e) {
console.log(`localStorage改变了: ${e.key}--${e.value}`)
})
// 改变localStorage中的'user'
localStorage.setItem('user', 'hhh')
Proxy的方法监听:
const handler = {
apply: function (target, thisArg, argumentsList) {
console.log(
`localStorage改变了: ${argumentsList[0]}--${argumentsList[1]}`
)
},
}
const proxy1 = new Proxy(Storage.prototype.setItem, handler)
proxy1('user', 'hahaha') // 输出: "localStorage改变了: user--hahah"
备注:
handler.apply方法可以拦截函数的调用
new Proxy的第一个参数target,可以是任何类型的对象,包括函数
还有一种监听:StorageEvent
MDN:当前页面使用的 storage 被其他页面修改时会触发 StorageEvent 事件.
[译者:事件在同一个域下的不同页面之间触发,即在 A 页面注册了 storge 的监听处理,只有在跟 A 同域名下的 B 页面操作 storage 对象,A 页面才会被触发 storage 事件]
// 页面a
window.addEventListener('storage', () => {
alert('storage被改了')
})
// 页面
localStorage.setItem('user', 'aasx')