11

私はIE8でカスタムイベントを発生させようとしていて、ここここから一緒に解決策をいじっています。しかし、私はそれを機能させることができません...

私はrequireJSとGoogleアナリティクスでjquery mobileを使用しています。だから私はJQMpageshowイベントを追跡しています。ただし、requireJS はスクリプトを非同期で読み込むため、pageshow へのバインドは JavaScript の「ラッパー」で行う必要があります。そうしないと、スニペットが解析されるまでに jquery も jquery mobile も読み込まれないため、エラーが発生します。

だから私はこれをすべてのページの最後に含めています:

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")}); 
}

検出されたら、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]);
        }); 
    } 
}; 

イベント チェーンを開始jqmReadyするには、JQM の準備ができたときにトリガーする必要があります。JQM はmobileinitイベントを使用して、まさにそれを示します。したがって、アプリケーション コントローラーの init 内で、次のようにバインドしています。

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

$(window).trigger('jqmReady') をトリガーしようとしましたmobileinitが、トリガーすると jquery が使用できるためです。ただし、で作成されたイベントはaddEventListenerこのようにトリガーできないようです。そのため、IE でカスタム イベントをトリガーするには JavaScript のみのソリューションが必要です。

質問:
IE8 の JavaScript カスタム イベントを正しくトリガーする方法を教えてもらえますか?

4

2 に答える 2

12

わかりました、私はついに理解しました...これがどのように機能するかです:

1)読み込まれるページでjqmReadyのリスナーを設定する

// 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);
        }
    });
}

したがって、IE8ではカスタムをリッスンしていませんjqmReady。代わりにonpropertychange、カスタムプロパティをリッスンしますjqmReady

2)次に、mobileinitで次のようにトリガーします。

 // 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++;
 };

いいアイデア(http://dean.edwards.name/weblog/2009/03/callbacks-vs-events/へのクレジット)、多分他の誰かがそれの使用法を見つけることができます。

于 2012-11-18T12:00:38.247 に答える
6

興味のある人のために、このコードを静的な JavaScript オブジェクトにまとめました。

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]++;
    }
}

利用方法:

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

Event.trigger('myevent');

デモ: http://jsfiddle.net/c5CuF/

于 2013-10-03T13:02:09.300 に答える