9

Próbuję wywołać niestandardowe zdarzenie na IE8 i skrzypce rozwiązanie razem z here i here. Ale nie mogę go uruchomić ...Jak wywołać niestandardowe zdarzenie javascript w IE8?

Używam jquery mobile z requireJS i google analytics. Śledzę więc wydarzenie JQM pageshow. Jednak ponieważ requireJS ładuje asynchroniczne skrypty, moje powiązanie z plikiem stronicowania musi być zrobione w "opakowaniu" javascript, w przeciwnym razie wygeneruje błąd, ponieważ ani jquery ani jquery mobile nie zostaną załadowane do czasu przeanalizowania fragmentu kodu.

Więc robię to w tym na końcu każdej strony:

if (document.addEventListener) { 
    document.addEventListener("jqmReady",function(){trigAnalytics("jqmReady");alert("FF detected")},false); 
} else if (document.attachEvent) { 
    document.attachEvent("jqmReady", function(){trigAnalytics("jqmReady");alert("IE detected")}); 
} 

A kiedy wykryte, jestem wypalania moje analityki snippet z wiążąca pageshow:

var trigAnalytics = function(trigger){ 
    $(document).on('pageshow','div:jqmData(role="page").basePage', function (event, ui) { 
     var url = location.href; 
     try { 
      hash = location.hash; 
      if (hash && hash.length > 1) { 
       _gaq.push(['_trackPageview', hash.substr(1)]); 
       _gaq.push(['_setCustomVar', 1, 'id_external', ########, 1 ]); 
      } else { 
       _gaq.push(['_trackPageview', url]); 
       _gaq.push(['_setCustomVar', 1, 'id_external', ########, , 1 ]); 
       _gaq.push(['b._trackPageview', url]); 
      } 
     } catch(err) { } 
    }); 
    if (typeof _gaq !== "undefined" && _gaq !== null) { 
     $(document).ajaxSend(function(event, xhr, settings){ 
      _gaq.push(['_trackPageview', settings.url]); 
      _gaq.push(['b._trackPageview', settings.url]); 
     }); 
    } 
}; 

Więc kopnięcie łańcucha zdarzeń, muszę uruchomić jqmReady, gdy JQM jest gotowy. JQM używa ich zdarzenia mobileinit, aby to zaznaczyć. Więc w mojej aplikacji kontrolera init mam wiązanie z nim tak:

$(document).bind("mobileinit", function() { 

    // non-IE OK 
    if (document.createEvent) { 
     evt = document.createEvent("Event"); 
     evt.initEvent("jqmReady", true, true); 
     document.dispatchEvent(evt); 

    } else if (document.createEventObject) { 
    // MSIE (NOT WORKING) 

     document.documentElement.evt = 0; // an expando property 
     document.documentElement.attachEvent("jqmReady", function() { 
      document.documentElement.evt = document.documentElement.evt + 1; 
      }); 
    } 
}); 

Próbowałem tylko wyzwalanie $ (okno) .trigger („jqmReady”), bo gdy mobileinit wyzwalacze, jQuery jest dostępna. Jednak wydaje się, że zdarzenia utworzone w addEventListener nie mogą być uruchamiane w ten sposób, więc potrzebuję rozwiązania tylko javascript, aby wyzwolić niestandardowe zdarzenie w IE.

Pytanie:
Czy ktoś może mi dać wskaźnik na jak wywołać javascript niestandardowe wydarzenie dla IE8 poprawnie?

+0

dlaczego nie umieścić ten spust $ (document) .ready()? dlaczego w ogóle możesz tego potrzebować? –

+0

Ponieważ 'jquery' ~ $ (document) .ready() nie będzie dostępny, gdy ten kod zostanie uruchomiony. Fragment znajduje się na stronie zaraz po inicjalizacji requireJS. Tak więc strona (1) jest analizowana, (2) wymaga wyzwalaczy JS, (3) mój fragment kodu jest wykonywany.Gdy to zrobi, ani 'jquery' ani' jquery-mobile' nie będą w pełni załadowane. Tak więc musi być tylko javascript. – frequent

+0

Nie jestem pewien, czy podążam za twoim pytaniem (stąd komentarz, nie odpowiadam), ale jest ['dispatchEvent()'] (https://developer.mozilla.org/en-US/docs/DOM/element.dispatchEvent) z stosowność? –

Odpowiedz

11

Ok, ale w końcu zrozumieć ... Oto jak to działa:

1) ustalanie słuchacza do jqmReady na stronie są ładowane

// non-IE: just create a listener for the custom event "jqmReady" 
if (document.addEventListener) { 
    document.addEventListener("jqmReady",function(){trigAnalytics("jqmReady");alert("FF detected")},false); 
// IE8 
} else if (document.attachEvent) { 

    // create a custom property name jqmReady and set it to 0 
    document.documentElement.jqmReady = 0; 
    // since IE8 does not allow to listen to custom events, 
    // just listen to onpropertychange 
    document.documentElement.attachEvent("onpropertychange", function(event) { 

     // if the property changed is the custom jqmReady property 
     if (event.propertyName == "jqmReady") { 
      trigAnalytics("jqmReady"); 
      alert("gotcha") 
      // remove listener, since it's only used once 
      document.documentElement.detachEvent("onpropertychange", arguments.callee); 
     } 
    }); 
} 

Więc na IE8 ja nie słucham za niestandardowe jqmReady. Zamiast tego słuchać onpropertychange dla mojego niestandardowego obiektu jqmReady

2) Następnie na mobileinit mam wyzwalającego tak:

// non-IE 
if (document.createEvent) { 
     evt = document.createEvent("Event"); 
     evt.initEvent("jqmReady", true, true); 
     document.dispatchEvent(evt); 
} else if (document.createEventObject) { // MSIE 
     // just change the property 
     // this will trigger onpropertychange 
     document.documentElement.jqmReady++; 
}; 

niezły pomysł (kredytowej http://dean.edwards.name/weblog/2009/03/callbacks-vs-events/), może ktoś inny może znaleźć zastosowanie dla niego .

+2

Jedną wadą 'onpropertychange' jest to, że się nie bańka. Musisz wiedzieć z góry, który element ma zmienioną właściwość. Więcej informacji na http://msdn.microsoft.com/en-us/library/ie/ms536956%28v=vs.85%29.aspx – dotnetCarpenter

6

Dla ktoś zainteresowany, mam owinięty ten kod do statycznej JavaScript Object

function Event() { 
} 

Event.listen = function (eventName, callback) { 
    if(document.addEventListener) { 
     document.addEventListener(eventName, callback, false); 
    } else {  
     document.documentElement.attachEvent('onpropertychange', function (e) { 
      if(e.propertyName == eventName) { 
       callback(); 
      }    
     }); 
    } 
} 

Event.trigger = function (eventName) { 
    if(document.createEvent) { 
     var event = document.createEvent('Event'); 
     event.initEvent(eventName, true, true); 
     document.dispatchEvent(event); 
    } else { 
     document.documentElement[eventName]++; 
    } 
} 

Wykorzystanie:

Event.listen('myevent', function() { 
    alert('myevent triggered!'); 
}); 

Event.trigger('myevent'); 

Demo: http://jsfiddle.net/c5CuF/

+0

nice. Możesz dodać metodę ".remove", aby prawidłowo zlikwidować zdarzenie niestandardowe. – frequent

+2

zrobił to [tutaj] (https://gist.github.com/frequent/6904575) – frequent

+0

sympatyczny kumpel: D – Elliott

Powiązane problemy