如何在 IE8 中触发自定义 javascript 事件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13435008/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 18:46:08  来源:igfitidea点击:

How to trigger a custom javascript event in IE8?

javascriptjqueryinternet-explorerjquery-mobilerequirejs

提问by frequent

I'm trying to fire a custom event on IE8 and fiddling a solution together from hereand here. But I cannot get it to work...

我正在尝试在 IE8 上触发一个自定义事件并从这里这里一起摆弄解决方案。但我无法让它工作......

I'm using jquery mobile with requireJS and google analytics. So I'm tracking the JQM pageshowevent. However since requireJS loads scripts async, my binding to pageshow needs to be made in a javascript "wrapper", otherwise it will produce an error, because neither jquery nor jquery mobile will have been loaded by the time the snippet is parsed.

我正在使用带有 requireJS 和谷歌分析的 jquery mobile。所以我正在跟踪 JQMpageshow事件。但是,由于 requireJS 异步加载脚本,我需要在 javascript“包装器”中进行我对 pageshow 的绑定,否则它将产生错误,因为在解析片段时,jquery 和 jquery mobile 都不会被加载。

So I'm doing including this at the end of every page:

所以我在每一页的末尾都包括这个:

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

And when detected, I'm firing my analytics snippet with the pageshow binding:

当检测到时,我会使用 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]);
        }); 
    } 
}; 

So to kick of the event chain, I need to trigger jqmReadywhen JQM is ready. JQM uses their mobileinitevent to indicate just that. So inside my application controller init, I'm binding to it like so:

所以要启动事件链,我需要jqmReady在 JQM 准备好时触发。JQM 使用他们的mobileinit事件来表明这一点。所以在我的应用程序控制器初始化中,我像这样绑定到它:

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

I have tried just triggering $(window).trigger('jqmReady'), because when mobileinittriggers, jquery is available. However it seems events created in addEventListenercan not be triggered like this, so I need a javascript-only solution to trigger a custom event in IE.

我试过只触发 $(window).trigger('jqmReady'),因为mobileinit触发时,jquery 可用。然而,似乎addEventListener无法像这样触发在中创建的事件,所以我需要一个仅限 javascript 的解决方案来触发 IE 中的自定义事件。

Question:
Can someone give me a pointer on how to trigger a javascript custom event for IE8 correctly?

问题:
有人能给我一个关于如何正确触发 IE8 的 javascript 自定义事件的指针吗?

回答by frequent

Ok, I finally understand... here is how it works:

好吧,我终于明白了......这是它的工作原理:

1) setting the listener for jqmReady on the page being loaded

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

So on IE8 I'm not listening for custom jqmReady. Instead I listen for onpropertychangefor my custom property jqmReady

所以在 IE8 上我没有在听 custom jqmReady. 相反,我会监听onpropertychange我的自定义属性jqmReady

2) Then on mobileinit I'm triggering like this:

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

Nice idea (credit to http://dean.edwards.name/weblog/2009/03/callbacks-vs-events/), maybe someone else can find a use for it.

好主意(归功于http://dean.edwards.name/weblog/2009/03/callbacks-vs-events/),也许其他人可以找到它的用途。

回答by Elliott

For anyone else interested, I've wrapped up this code into a static javascript object

对于其他感兴趣的人,我已将此代码包装到一个静态 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]++;
    }
}

usage:

用法:

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

Event.trigger('myevent');

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

演示:http: //jsfiddle.net/c5CuF/