2013-08-16 11 views
9

Program Internet Explorer 10 uruchamia zdarzenie "storage" okna w tym samym oknie, które zostało zapisane w pamięci lokalnej.Dlaczego Internet Explorer uruchamia zdarzenie "przechowywania" okna w oknie, w którym przechowywane są dane?

Wygląda na to, że inne przeglądarki wywołują zdarzenie tylko we wszystkich innych oknach, więc nie muszę się martwić o okno, które nasłuchuje zdarzeń pamięci masowej reagujących na własne przechowywanie. Dlaczego IE uruchamia zdarzenie w niewłaściwym oknie i jak mogę zreplikować standardowe zachowanie w IE?

Odpowiedz

9

Microsoft wydaje się być świadomi problemu, ale nie wygląda na to, że zamierzamy go naprawić w najbliższym czasie: https://connect.microsoft.com/IE/feedback/details/774798/localstorage-event-fired-in-source-window

Jedną z opcji jest to, że można zaprojektować słuchaczy i ustawiające tak, że nie reaguj ani nie przechowuj, gdy otrzymają informacje ze zdarzenia pamięci masowej, które jest już zgodne z ich stanem. Jednak ten wzorzec projektowania może być trudniejszy niż poleganie na zdarzeniu pamięci masowej, które jest uruchamiane tylko w innych oknach.

Inną opcją jest sprawienie, aby lokalne przechowywanie działało tak samo w IE, że działa w innych przeglądarkach. Wymyśliłem wprawdzie hacky, ale funkcjonalne rozwiązanie, które przetestowałem w IE10 i oczekuję pracy w IE8 i IE9. Moje składniki javascript nie nasłuchują bezpośrednio zdarzenia "storage" okna, ale zamiast tego nasłuchują "utworzonego przeze mnie dispatchera zdarzeń". Program rozsyłający zdarzenia nasłuchuje zdarzenia "magazynowania" okna i wyzwala zdarzenie szkieletowe, O ile zdarzenie magazynowania nie pochodzi z tego okna. Tak jak ja sprawdzić, czy to okno przechowywane ta wartość jest za pomocą metody niestandardowej za nazwanie setItem(), która tworzy unikatowy identyfikator dla wartości i śledzi to, jak ten:

eventDispatcher.set = function(key, value) { 
    var storageId = (new Date()).getTime(); 
    eventDispatcher.idList.push(storageId); 
    localStorage.setItem(key, {value: value, id: storageId}); 
} 

A moja EventDispatcher słucha zdarzenia przechowywania i wyzwala zdarzenie tylko wtedy, gdy lista identyfikatorów to stworzone nie zawiera identyfikatora wartość ta, podobnie jak to:

$(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']); 
} 

jest trochę więcej kodu można dodać do utrzymania obiektu IDList krótkie i utworzyć go jako najpierw pusta tablica, ale zostawiłem to dla jasności. Utworzenie eventDispatchera w celu obsługi zdarzeń pamięci masowej jest nieco zbyteczne, ale może sprawić, że twój rozwój będzie spójny między przeglądarkami. Mniej nieprzyjemne rozwiązanie korzystałoby z odpowiedniego mechanizmu blokowania i kolejkowania, ale może to być bardzo trudne.

+1

Czy masz jakąś szansę na to, jak wygląda Twój dyspozytor zdarzeń? – Jesse

+2

Jesse, spójrz, jak to rozwiązano tutaj https://github.com/Shadez/ls-notifier/blob/master/js/notifier.js – Denis

+1

W tej odpowiedzi brakuje istotnych informacji. – Cerbrus

Powiązane problemy