localStorage
にはstorage
というイベントがあり,localStorage
に変更があった場合に発火します
このstorage
イベントはlocalStorage
を変更したドキュメント以外の,同じlocalStorage
を共有しているwindow
(タブ)で発火します。
変更を加えたドキュメント内では何も起きません。
storage
イベントのevent
オブジェクトのプロパティにはlocalStorage
にどんな変更を加えたかの情報がないので,プロパティの値から判定する必要があります。(あるよね?)
storageイベントが発火するタイミング
storage
イベントはlocalStorage
に変更が加えられたときにだけ発火します。変更がない場合には発火しません。
実行するメソッドと状況によるイベント発火の有無
メソッド | 状況 | タイプ | イベント発火 |
---|---|---|---|
.getItem(key) | すべて | 取得 | ☓ |
.setItem(key, value) | keyが存在しない場合 | 追加 | ○ |
keyが存在してて既存のvalueとsetするvalueが違う | 更新 | ○ | |
keyが存在してて既存のvalueとsetするvalueが同じ | --- | ☓ | |
.removeItem(key) | keyが存在している | 削除 | ○ |
keyが存在しない | --- | ☓ | |
.clear() | localStorage内にkeyが1つ以上存在している | 全削除 | ○ |
localStorage内にkeyが1つも存在しない | --- | ☓ |
.getItem()
ではあらゆる状況で発火しません。
.setItem()
もkey
がすでに存在してる&&setするvalue
が一緒の場合は発火しません。
.removeItem()
は削除しようとしたkey
が存在しない場合発火はしません。
.clear()
はlocalStorage
に値が1つも入っていない場合は発火しません。
各タイプのevent
オブジェクトのプロパティの値
それぞれのタイプごとのeventオブジェクト内の主要な(判定に使う)プロパティは以下のようになります。
| タイプ | key | oldValue | newValue |
|:------|:------|:------|:------|:------|
| 追加 | key | null | value |
| 更新 | key | oldValue | value |
| 削除 | key | oldValue | null |
| 全削除 | "" | null | null |
タイプを判定する
基本的にはoldValue
とnewValue
の値のチェックで判定できます。
clear
の判定には念のためstorageArea
の要素数をチェックしています。
<h1>receiveStorageEvent</h1>
<script src="./detectStorageEventType.js"></script>
window.addEventListener("storage", function (event) {
var oldValue = event.oldValue;
var newValue = event.newValue;
var storageArea = event.storageArea;
/* console.log(event) */
if( oldValue === null && newValue !== null){
console.log( "type : add" );
}else if( oldValue !== null && newValue === null){
console.log( "type : remove" );
}else if( oldValue !== null && newValue !== null){
console.log( "type : update" );
}else if( oldValue === null && newValue === null && storageArea.length === 0){
console.log( "type : clear" );
}
});
<h1>sendStorageEvent</h1>
<button id="set">set</button>
<button id="update">update</button>
<button id="get">get</button>
<button id="remove">remove</button>
<button id="clear">clear</button>
<script>
document.addEventListener( "DOMContentLoaded", function(){
document.getElementById( "set" ).addEventListener( "click", function(){
localStorage.setItem( "hoge", "setitem" );
});
document.getElementById( 'update').addEventListener( "click", function(){
localStorage.setItem( "hoge", "update" );
});
document.getElementById( "get" ).addEventListener( "click", function(){
localStorage.getItem( "hoge" );
});
document.getElementById( "remove" ).addEventListener( "click", function(){
localStorage.removeItem( "hoge" );
});
document.getElementById( "clear" ).addEventListener( "click", function(){
localStorage.clear();
});
});
</script>
つかいかた
同じブラウザで2つのHTMLファイルを開きます。
sendStorageEvent.html
でlocalStorage
の値を操作するとreceiveStorageEvent.html
のコンソールに各タイプの判定結果が出力されます。