[JavaScript] IE11ではonStorageイベントの挙動が異なる


JavaScriptのonStorageイベントはブラウザによって挙動が異なるので、紹介します。(2018年11月現在)

動作環境
OS: Windows 10 Pro
Google Chrome: 70.0.3538.110
Mozilla Firefox: 63.0.3
Microsoft Edge: 42.17134.1.0
Microsoft Internet Explorer: 11.407.17134.0

onstorageとは

Web Storageの1つであるLocalStorageに変化が起こった場合にイベントが発生します。
https://developer.mozilla.org/ja/docs/Web/API/WindowEventHandlers/onstorage

以下のデモページをブラウザのタブを2つにしてそれぞれ表示してみてください。
デモはこちら
ソースファイルはこちら

LocalStorageのsetItemgetItemremoveItemclear の動作が確認できます。onStorageを確認するためには、「input:」テキストボックスに文字を入力して「setItem」ボタンを押下してください。LocalStorageの値が変わり、別のタブの「Log:」イベントが通知されます。「abcdefg」をsetItemにすると別のタブに以下のログが表示されます。

Log
onstorage: key=itemKey, oldValue=null, newValue=abcdefg

以下のような実装になっています。

index.js
$('#setItemButton').on('click', function () {
  var itemValue = $('#itemInput').val();
  localStorage.setItem('itemKey', itemValue);
});

window.onstorage = function (e) {
  log('onstorage: key=' + e.key + ', oldValue=' + e.oldValue + ', newValue=' + e.newValue);
};

ブラウザ毎のonStorageの挙動

IE11とその他のブラウザでは、onStorageイベントの挙動が異なります。IE11では、setItemを実行したタブとその他のタブの両方にonStorageイベントが通知されます。その他のブラウザでは、その他のタブの片方のみ通知されます。

ブラウザ名 setItemを実行したタブ その他のタブ
Google Chrome 通知されない 通知される
Mozilla Firefox 通知されない 通知される
Microsoft Edge 通知されない 通知される
Microsoft Internet Explorer 通知される 通知される

複数タブの同期 (onChange)

onStorageイベントを利用して、複数タブでテキストボックスの値を同期してみたいと思います。

以下のデモページをブラウザのタブを2つにしてそれぞれ表示してみてください。
デモはこちら
ソースファイルはこちら

「input:」テキストボックスに文字を入力すると、別のタブにその内容が反映されています。テキストボックスでonChangeイベントが通知されるとsetItemを実行しています。そのため、別タブにonStorageイベントが通知されて、別タブのテキストボックスに反映されます。

index.js
$('#itemInput').on('change', function () {
  // テキストボックスのフォーカスが外れたタイミングで呼ばれる
  var itemValue = $('#itemInput').val();
  localStorage.setItem('itemKey', itemValue);
});

window.onstorage = function (e) {
  log('onstorage: key=' + e.key + ', oldValue=' + e.oldValue + ', newValue=' + e.newValue);
  $('#itemInput').val(e.newValue);
};

複数タブの同期 (onKeyup)

onChangeイベントと同様に、onKeyupイベントでテキストボックスの値を同期してみたいと思います。

以下のデモページをブラウザのタブを2つにしてそれぞれ表示してみてください。
デモはこちら
ソースファイルはこちら

index.js
$('#itemInput').on('keyup', function () {
  // キーボードのキーを離したタイミングで呼ばれる
  var itemValue = $('#itemInput').val();
  localStorage.setItem('itemKey', itemValue);
});

window.onstorage = function (e) {
  log('onstorage: key=' + e.key + ', oldValue=' + e.oldValue + ', newValue=' + e.newValue);
  $('#itemInput').val(e.newValue);
};

引用

[Javascript] IE11ではonStorageイベントの挙動が異なる