Как привязать к событию изменения localStorage, используя jQuery для всех браузеров?

Как связать функцию с событием изменения localStorage HTML5 с помощью jQuery?

$(function () {

  $(window).bind('storage', function (e) {
    alert('storage changed');
  });

  localStorage.setItem('a', 'test');

});

Я пробовал выше, но предупреждение не отображается.

Обновление: это работает в Firefox 3.6, но не работает в Chrome 8 или IE 8, поэтому вопрос должен быть больше "Как привязать событие localStorage к изменению, используя jQuery для всех браузеров?"

5 ответов

Решение

Оказывается, это на самом деле работает правильно, и я неправильно истолковал спецификацию

Когда методы setItem(), removeItem() и clear() вызываются для объекта Storage x, который связан с локальной областью хранения, если методы что-то сделали, то в каждом объекте Document, у которого объект Storage атрибута localStorage объекта Window равен связанный с той же областью хранения, кроме x, событие памяти должно быть запущено

Другими словами, событие хранения запускается в каждом окне / вкладке, за исключением того, которое обновило localStorage объект и вызвал событие.

Так что событие не было запущено, потому что у меня было открыто только одно окно / вкладка. Если бы я поместил вышеуказанный код на страницу и открыл страницу на двух вкладках, я бы увидел событие, запущенное на второй вкладке.

Этот ответ на проблему содержит более подробную информацию.

Вот как это сделать в JQuery:

 $(window).bind('storage', function (e) {
     console.log(e.originalEvent.key, e.originalEvent.newValue);
 });

Доступ к e.key напрямую не работает. Вам нужно использовать e.originalEvent.key,

Некоторые браузеры отправляют уведомления о хранении только на другие вкладки, а некоторые нет. (Firefox будет отправлять события хранения на свою вкладку, но с key установить на ноль, похоже).

Стоит упомянуть, что обработчик событий вызывается только .setItem если элемент действительно меняется. Я рвал на себе волосы, пытаясь заставить это работать, пока не понял, что вы не можете продолжать запускать setItem с тем же значением.

Я на Chrome версии 54.0.2840.71 м

Вот тест (откройте его в двух вкладках браузера).

if (window.addEventListener)
            addEventListener('storage', storage_event, false);
        else if (window.attachEvent)
            attachEvent('onstorage', storage_event, false);
        function storage_event(e) {
            console.log("Time is now "+ e.newValue);
        }

        setInterval(function () {
            var time=new Date().getTime();
            localStorage.setItem("time", time);
            console.log("Setting time to "+time);
        }, 1000)

Вы всегда можете использовать такую ​​утилиту, как localDataStorage, чтобы запускать события для вас в одном и том же окне / вкладке при каждом изменении значения ключа, например, сделанного методами set или remove. Вы также можете использовать его для прозрачной установки / получения любого из следующих "типов": Array, Boolean, Date, Float, Integer, Null, Object или String.

[ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ] Я являюсь автором утилиты [/ ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ]

Как только вы создадите экземпляр утилиты, следующий фрагмент позволит вам отслеживать события (в vanilla JS, так как примеры jQuery уже были приведены):

function localStorageChangeEvents( e ) {
    console.log(
        "timestamp: "     + e.detail.timestamp + " (" + new Date( e.detail.timestamp ) + ")" + "\n" +
        "key: "           + e.detail.key     + "\n" +
        "old value: "     + e.detail.oldval  + "\n" +
        "new value: "     + e.detail.newval  + "\n"
    );
};
document.addEventListener(
    "localDataStorage"
    , localStorageChangeEvents
    , false
);

Обновление ответа @Flimm;.bind()метод устарел после jQuery 3.0, поэтому использование.on()метод рекомендуется.

      $(window).on('storage', function (e) {
  console.log(e.originalEvent.key, e.originalEvent.newValue);
});
Другие вопросы по тегам