如何在IE8中触发自定义javascript事件?
我试图在IE8上发起一个自定义事件,并从这里和这里一起摆弄一个解决方案。 但我不能让它工作……
我正在使用带有requireJS和谷歌分析的jquery mobile。 所以我正在跟踪JQM pageshow
事件。 但是由于requireJS加载脚本async,我对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]); }); } };
因此,为了启动事件链,我需要在JQM准备就绪时触发jqmReady
。 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
创建的事件,因此我需要一个仅限javascript的解决方案来触发IE中的自定义事件。
题:
有人能给我一个关于如何正确触发IE8自定义事件的指针吗?
好的,我终于明白了…这是它的工作原理:
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
。 相反,我为我的自定义属性jqmReady
监听onpropertychange
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/ ),也许其他人可以找到它的用途。
对于其他感兴趣的人,我已将此代码包装到静态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/