H5 標准新增的本地存儲 localStorage 已經很熟悉了,但是還有個 storage 事件監聽確實比較陌生,這個事件可以通過更新 localstorage 來觸發,而且當前在同一個瀏覽器下打開的所有同源頁面都可以監聽得到!下面我們就來具體了解一下:
一、Storage事件介紹
1、storage 事件
在某些復雜情況下,如果多個頁面都需要訪問本地存儲的數據,就需要在存儲區域的內容發生改變時,能夠通知相關的頁面。
Web Storage API 內建了一套事件通知機制,當存儲區域的內容發生改變(包括增加、修改、刪除數據)時,就會自動觸發 storage 事件,並把它發送給所有感興趣的監聽者。因此,如果需要跟蹤存儲區域的改變,就需要在關心存儲區域內容的頁面監聽 storage 事件。(所有支持 localStorage 的瀏覽器都支持 storage 事件)
if (window.addEventListener) { window.addEventListener("storage", handleStorage, false); } // handleStorage 回調函數接受一個 StorageEvent 參數
function handleStorage(e) { ...... }
此時,變量 e 就是一個 StorageEvent 對象,這個對象有很多有用的屬性。
2、StorageEvent 對象介紹
storage 事件的處理函數接受的 event 事件對象也和通常的事件對象不同,這些屬性如下:
//StorageEvent對象
{ bubbles: false, cancelBubble: false, cancelable: false, composed: false, currentTarget: {...}, //當前Window對象
defaultPrevented: false, eventPhase: 0, isTrusted: true, key: "tabs",//更新的item鍵名
newValue: "1",//更新后的item鍵值
oldValue: "2",//更新前的item鍵值
path: [Window],//一個數組,數組中有一個元素,為當前Window對象
returnValue: true, srcElement: {...}, //當前Window對象
storageArea: {...}, //Storage對象
target:{...}, //當前Window對象
timeStamp: 101647.2000000067, type: "storage", url: "http://www.localhost.com/list.html",//更新localStorage的頁面
__proto__: StorageEvent }
我們常用的有如下幾個重要的屬性,通過這些屬性我們可以做很多操作,例如頁面之間互相傳值,統計當前打開的頁面數量(限同源頁面)等。
屬性 | 含義 |
key | 設置或刪除或修改的鍵。調用clear()時,則為null。 |
oldValue | 改變之前的舊值。如果是新增元素,則為null。 |
newValue | 改變之后的新值。如果是刪除元素,則為null。 |
storageArea | 該屬性是一個引用,指向發生變化的sessionStorage或localStorage對象 |
url | 觸發這個改變事件的頁面的URL |
target | 當前窗口對象 |
3、注意點:需要注意的是
(1)只有在數據的內容確實發生改變的時候,才會觸發 storage 事件。如果把一個值設置成一模一樣的值,或刪除一個根本就不存在的存儲項,則不會觸發 storage 事件。
(2)並且,storage 事件只會發送給同源、而且處於打開狀態的其它頁面,而不會發送給觸發改變的頁面本身及處於關閉狀態的頁面。
二、storage 事件應用
QQ音樂的主頁是 https://y.qq.com,而實際播放的頁面是 https://y.qq.com/n/ryqq/player。當你在其他頁面(我們隨便選一個歌單列表:https://y.qq.com/n/ryqq/playlist/7777601718)點擊播放或者添加的時候,你會發現 https://y.qq.com/n/ryqq/player 里的歌曲播放狀態會實時的變化。
那我們就來探究一下 QQ 音樂的實現。
點擊播放歌曲的時候,在 player 頁面即播放頁面捕獲的數據。這就完全驗證了 QQ音樂這個添加音樂的實現就是基於 storage 事件來完成的。