I. About Getting Event Object##
FF is a bit stubborn, only supports arguments[0], doesn't support window.event. This time it's really not IE's fault, although having event as a property of window doesn't conform to specifications, but everyone has tacitly allowed this small problem to exist, only FF has been independent after all these years. So, there are two ways to get cross-browser event objects:
-
With parameters:
getEvent : function(event){ return event ? event : window.event; //return event || window.event;//or simpler way } -
Without parameters:
function getEvent() { return arguments[0] ? arguments[0] : window.event; //return arguments[0] || window.event;//or simpler way }
Need to特别说明 a way: HTML's DOM Level 0 method + event handler with parameters, as follows:
function handler(event){
//do something
}
<!-- HTML 的 DOM0 级方式 -->
<button id="btn" onclick="handler(event);">按钮</button>
The above method is fully browser compatible, but the disadvantage of relying on HTML's DOM Level 0 method is obvious, so it didn't become a mainstream method like the first two. And JS's DOM Level 0 method + event handler with parameters, as follows:
function handler(event){
//do something
}
btn.onclick = handler;//JS 的 DOM0 级方式
//btn.onclick = function(event){/*do something*/}//or anonymous function, same effect as above
This method is not fully browser compatible, [IE8-] doesn't support, IE9+ unknown, FF, Chrome support. Always thought HTML's DOM Level 0 event handling and JS's DOM Level 0 event handling were equivalent, now after doing many experiments discovered there are differences between the two
II. About Getting Event Source##
event.srcElement is [IE8-] only method, IE9+ unknown, other browsers all support standard event.target method
III. About Preventing Default Event Behavior##
event.preventDefault() is standard method, but [IE8-] doesn't support, IE's own method is event.returnValue = false;
IV. About Stopping Event Propagation##
event.stopPropagation() is standard method, IE has objections again, he wants to play like this: event.cancelBubble = true;Need to pay special attention here, because cancel is a property not a method, very different from standard, easy to remember wrong
V. About Adding and Removing Event Handlers##
- DOM Level 0 method
ele.onclick = handler;ele.onclick=null;The oldest method
Advantages: Fully browser compatible
Disadvantages: Can only bind/unbind one event handler for the same event
- DOM Level 2 method
ele.add/removeEventListener(eventType, handler, catch);
And IE method: ele.attach/detachEvent('on'+eventType, handler);
Advantages: Supports binding/unbinding multiple event handlers
Disadvantages: Need to do compatibility judgment. Need to note: in standard method the last parameter indicates whether to bind/unbind during event capture phase, IE doesn't support event capture, so there's no third parameter
Note: IE method not only has different method name from standard, event type in parameters also needs to add on, otherwise binding is invalid but doesn't error
VI. Cross-Browser Event Handling##
//跨浏览器的事件处理器添加方式
var EventUtil = {
addHandler : function(elem, type, handler){
if(elem.addEventListener){
elem.addEventListener(type, handler, false);
}
else if(elem.attachEvent){
elem.attachEvent("on" + type, handler);//添加多个同一类型的 handler 时,IE 方式的规则是最后添加的最先触发
}
else{
if(typeof elem["on" + type] === 'function'){
var oldHandler = elem["on" + type];
elem["on" + type] = function(){
oldHandler();
handler();
}
}
else{
elem["on" + type] = handler;//支持添加多个事件处理���
}
}
},
getEvent : function(event){
return event ? event : window.event;
},
getTarget : function(event){
return event.target || event.srcElement;
},
preventDefault : function(event){
if(event.preventDefault){
event.preventDefault();
}
else{
event.returnValue = false;
}
},
removeHandler : function(elem, type, handler){
if(elem.removeEventListener){
elem.removeEventListener(type, handler, false);
}
else if(elem.detachEvent){
elem.detachEvent("on" + type, handler);
}
else{
elem["on" + type] = null;//不支持移除单一事件处理器,只能全部移除
}
},
stopPropagation : function(event){
if(event.stopPropagation){
event.stopPropagation();
}
else{
event.cancelBubble = true;
}
},
getRelatedTarget : function(event){
if(event.relatedTarget){
return event.relatedTarget;
}
else if(event.toElement && event.type == "mouseout"){
return event.toElement;
}
else if(event.fromElement && event.type == "mouseover"){
return event.fromElement;
}
else{
return null;
}
},
/*IE8 点击左键和中键都是 0;FF 无法识别中键;Chrome 正常*/
getButton : function(event){//返回 0,1,2 - 左,中,右
if(document.implementation.hasFeature("MouseEvents", "2.0")){
return event.button;
}
else{
switch(event.button){
case 0:case 1:case 3:case 5:case 7:
return 0;
break;
case 2:case 6:
return 2;
break;
case 4:
return 1;
break;
default:
break;
}
}
},
/*只能检测 keypress 事件,返回值等于将要显示的字符编码*/
/*IE 和 Chrome 只有能显示的字符键才触发,FF 其它键也能触发,返回值为 0*/
getCharCode : function(event){
if(typeof event.charCode == "number"){
return event.charCode;
}
else{
return event.keyCode;
}
}
};
The above code is organized from "JavaScript Advanced Programming" Chinese edition, there's a small problem with getRelatedTarget in the book (P373), this article has made corrections
The addHandler in the book doesn't support adding multiple event handlers in DOM Level 0 method, after modification it can support, but doesn't support removing single event handler, so the code is still incomplete. If you want to support DOM Level 0 event handler add/remove operations, you can manually maintain an event handler queue. Given that implementing this method has little significance, won't expand here
No comments yet. Be the first to share your thoughts.