如何监听 LocalStorage 的变化?

572 阅读1分钟

消息订阅与发布

// 先保存一份原来的方法
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')