我正在尝试在IE8上触发自定义事件,并从here和here一起摆弄解决方案。但我无法让它发挥作用......
我正在使用带有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自定义事件的指针吗?
答案 0 :(得分: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/),也许其他人可以找到它的用途。
答案 1 :(得分: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');