當 localStorage 或 sessionStorage 數據發生變化時,瀏覽器會在**同源的其他標籤頁/窗口**中觸發 storage 事件。**觸發變化的當前頁面不會收到該事件**(IE 除外)。
The storage event is fired when a storage area changes... at each Window object whose Document object has a Storage object that is affected.
StorageEvent 接口。| 屬性 | 說明 |
|---|---|
key | 被修改的鍵名;若 clear() 則為 null。 |
oldValue | 修改前的值;新增鍵時為 null。 |
newValue | 修改後的值;刪除鍵時為 null。 |
url | 觸發變化的文檔 URL(來源頁面)。 |
storageArea | 觸發變化的 Storage 對象(localStorage/sessionStorage)。 |
<input id="inp" placeholder="輸入值"> <button id="btn">存入</button>
<script>
const inp = document.getElementById('inp');
const btn = document.getElementById('btn');
btn.onclick = () => {
const v = inp.value.trim();
if (!v) return;
localStorage.setItem('syncKey', v);
// 當前頁**不會**觸發 storage 事件
};
// 監聽其他頁變化(可選)
window.addEventListener('storage', e => console.log('A 收到:', e));
</script>
<script>
window.addEventListener('storage', e => {
console.log('B 收到:', e);
document.body.innerHTML = `oldValue: ${e.oldValue}, newValue: ${e.newValue}`;
// 這裡可同步更新 UI、重新渲染列表等
});
</script>
window.dispatchEvent(new StorageEvent('storage', {...})) 或封裝統一 setItem 方法內部自觸發。e.url === location.href 判斷)。localStorage 寫入拋異常,需 try-catch。const StorageBus = {
set(key, val) {
const old = localStorage.getItem(key);
localStorage.setItem(key, val);
// 手動觸發當前頁邏輯
window.dispatchEvent(new StorageEvent('storage', {
key, oldValue: old, newValue: val, url: location.href, storageArea: localStorage
}));
},
get(key) { return localStorage.getItem(key); },
remove(key) { localStorage.removeItem(key); },
onChange(cb) { window.addEventListener('storage', cb); },
offChange(cb) { window.removeEventListener('storage', cb); }
};
storage 事件是瀏覽器原生提供的**輕量級跨標籤頁總線**,零依賴、零配置、極低延遲。掌握其「異頁觸發、同源限制、事件屬性」三大特性,即可構建健壯的多頁同步體驗。