Internet Explorer 10 は、ローカル ストレージに格納されたウィンドウと同じウィンドウで、ウィンドウの "storage" イベントを発生させます。
他のブラウザは他のすべてのウィンドウでのみイベントを発生させるように見えるので、ストレージ イベントをリッスンしているウィンドウが独自の保存に反応することを心配する必要はありません。IE が間違ったウィンドウでイベントを発生させるのはなぜですか? また、IE で標準の動作を再現するにはどうすればよいですか?
Internet Explorer 10 は、ローカル ストレージに格納されたウィンドウと同じウィンドウで、ウィンドウの "storage" イベントを発生させます。
他のブラウザは他のすべてのウィンドウでのみイベントを発生させるように見えるので、ストレージ イベントをリッスンしているウィンドウが独自の保存に反応することを心配する必要はありません。IE が間違ったウィンドウでイベントを発生させるのはなぜですか? また、IE で標準の動作を再現するにはどうすればよいですか?
マイクロソフトはこの問題を認識しているようですが、すぐに修正する予定はないようです: https://connect.microsoft.com/IE/feedback/details/774798/localstorage-event-fired -ソース ウィンドウ内
1 つのオプションは、リスナーとセッターを設計して、既に状態と一致しているストレージ イベントから情報を取得したときに、それらが反応したり保存したりしないようにすることです。ただし、この設計パターンは、他のウィンドウでのみ発生するストレージ イベントに依存するよりも難しい場合があります。
もう 1 つのオプションは、ローカル ストレージを他のブラウザーと同じように IE で動作させることです。IE10 でテストし、IE8 と IE9 で動作することを期待している、確かにハッキーだが機能的なソリューションを思いつきました。私の JavaScript コンポーネントは、ウィンドウの「ストレージ」イベントを直接リッスンするのではなく、作成した「イベント ディスパッチャ」をリッスンします。イベント ディスパッチャは、ウィンドウの「ストレージ」イベントをリッスンし、ストレージ イベントがそのウィンドウで発生しない限り、バックボーン イベントをトリガーします。このウィンドウがこの値を格納しているかどうかを確認する方法は、次のように、値の一意の ID を作成して追跡する setItem() を呼び出すためのカスタム メソッドを使用することです。
eventDispatcher.set = function(key, value) {
var storageId = (new Date()).getTime();
eventDispatcher.idList.push(storageId);
localStorage.setItem(key, {value: value, id: storageId});
}
そして、私の eventDispatcher はストレージ イベントをリッスンし、作成した ID のリストにこの値の ID が含まれていない場合にのみ、次のようにイベントをトリガーします。
$(window).on('storage', dispatchStorageEvent);
function dispatchStorageEvent(event) {
var newValue = JSON.parse(event.originalEvent.newValue);
if (eventDispatcher.idList.indexOf(newValue['id']) > -1) {
return;
}
eventDispatcher.trigger("storageEvent:" + event.originalEvent.key, newValue['value']);
}
最初に idList を短くして空の配列として作成するために追加できるコードがもう少しありますが、わかりやすくするために省略しました。ストレージ イベントを処理するように eventDispatcher を作成すると、多少のオーバーヘッドが生じますが、ブラウザー間で開発の一貫性を保つことができます。ハックの少ない解決策は、適切なロックとキューイングのメカニズムを使用することですが、それは非常に困難な場合があります。