DEV Community

Cover image for 監聽 localStorage 事件:如何在同一頁面內偵測變更
Let's Write
Let's Write

Posted on • Originally published at letswrite.tw

監聽 localStorage 事件:如何在同一頁面內偵測變更

本篇要解決的問題

我們有時會把資訊存在瀏覽器的空間裡,像是 CookiesLocal StorageIndexedDB

Local Storage 原生的 storage 事件主要用於跨分頁同步,如下:

window.addEventListener("storage", () => {});
Enter fullscreen mode Exit fullscreen mode

但如果想要在同一個頁面內監聽變更,就需要手動覆寫 localStorage 方法。


localStorage event listener

我們可以透過 Storage.prototype 覆寫 setItem 等方法,並在其中加入 CustomEvent 來觸發變更事件。

// 保存原始方法
Storage.prototype._setItem = Storage.prototype.setItem;
Storage.prototype._getItem = Storage.prototype.getItem;
Storage.prototype._removeItem = Storage.prototype.removeItem;
Storage.prototype._clear = Storage.prototype.clear;

// 覆寫 setItem
Storage.prototype.setItem = function(key, value) {
    const oldValue = this._getItem(key);
    this._setItem(key, value);

    const evt = new CustomEvent('storagechange', {
        detail: {
            type: 'set',
            key: key,
            newValue: value,
            oldValue: oldValue
        }
    });
    window.dispatchEvent(evt);
};

// 覆寫 getItem
Storage.prototype.getItem = function(key) {
    const value = this._getItem(key);

    const evt = new CustomEvent('storagechange', {
        detail: {
            type: 'get',
            key: key,
            value: value
        }
    });
    window.dispatchEvent(evt);

    return value;
};

// 覆寫 removeItem
Storage.prototype.removeItem = function(key) {
    const oldValue = this._getItem(key);
    this._removeItem(key);

    const evt = new CustomEvent('storagechange', {
        detail: {
            type: 'remove',
            key: key,
            oldValue: oldValue
        }
    });
    window.dispatchEvent(evt);
};

// 覆寫 clear
Storage.prototype.clear = function() {
    this._clear();

    const evt = new CustomEvent('storagechange', {
        detail: {
            type: 'clear'
        }
    });
    window.dispatchEvent(evt);
};

// 監聽事件
window.addEventListener('storagechange', e => {
    console.log('LocalStorage 變更:', e.detail);
});
Enter fullscreen mode Exit fullscreen mode

Top comments (0)