Home  >  Article  >  Web Front-end  >  Detailed interpretation of JavaScript’s cross-browser event handling_Basic knowledge

Detailed interpretation of JavaScript’s cross-browser event handling_Basic knowledge

WBOY
WBOYOriginal
2016-05-16 15:45:351080browse

1. About getting the event object

FF is a bit stubborn and only supports arguments[0] and does not support window.event. I really don’t blame IE this time. Although using event as a window attribute is against the norm, everyone has already acquiesced to the existence of this small problem. Only FF has been unique after so many years. Therefore, there are two ways to obtain cross-browser event objects:

With ginseng:

getEvent : function(event){
  return event ? event : window.event;
  //return event || window.event;//或者更简单的方式
}

Without ginseng:

function getEvent() {
  return arguments[0] ? arguments[0] : window.event;
  //return arguments[0] || window.event;//或者更简单的方式
}

One method needs to be explained in particular: HTML’s DOM0 level method, event handler with parameters, as follows:

function handler(event){
  //do something
}
<!-- HTML的DOM0级方式 --><br /><button id="btn" onclick="handler(event);">按钮</button><br />

The above method is compatible with all browsers, but the shortcomings of relying on HTML's DOM0 level method are obvious, so it has not become a mainstream method like the first two, and JS's DOM0 level method has event processing with parameters. device, as follows:

function handler(event){
  //do something
}
btn.onclick = handler;//JS的DOM0级方式
//btn.onclick = function(event){/*do something*/}//或者匿名函数,效果同上

This method is not compatible with all browsers, [IE8-] is not supported, IE9 is unknown, FF, and Chrome support it. I always thought that HTML's DOM0 level event processing and JS's DOM0 level event processing were equivalent. Now I have done a lot of experiments and found that there is a difference between the two

2. About obtaining the event source

event.srcElement is the only method for [IE8-], IE9 is unknown, other browsers support the standard event.target method

3. About the default behavior of blocking events

event.preventDefault() is a standard method, but [IE8-] does not support it. IE’s own method is event.returnValue = false;

4. Regarding stopping the spread of events

event.stopPropagation() is a standard method. IE has another objection. He wants to play like this: event.cancelBubble = true; special attention needs to be paid here because cancel is an attribute rather than a method. It is far from the standard and easy to use. Misremembered

5. About adding and removing event handlers

DOM level 0 method

ele.onclick = handler;ele.onclick=null;The oldest way

Advantages: Compatible with all browsers

Disadvantage: The same event can only bind/unbind one event handler

DOM level 2 method

ele.add/removeEventListener(eventType, handler, catch);

And IE mode: ele.attach/detachEvent(‘on’ eventType, handler);

Advantages: Supports binding/unbinding multiple event handlers

Disadvantages: Compatibility judgment needs to be made. It should be noted that the last parameter in the standard method indicates whether to bind/unbind during the event capture phase. IE does not support event capture, so there is no third parameter

Note: In IE method, not only the method name is different from the standard, but also the event type in the parameter must be added with on, otherwise the binding will be invalid but no error will be reported

6. 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 &#63; 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;
    }
  }
};

Comprehensive example

If a library such as jQuery is not used in the project, how can one easily bind events to elements and make them compatible with various browsers? The following simple Utility should be considered.

var eventUtility = {
  addEvent : function(el, type, fn) {
    if(typeof addEventListener !== "undefined") {
      el.addEventListener(type, fn, false);
    } else if(typeof attachEvent !== "undefined") {
      el.attachEvent("on" + type, fn);
    } else {
      el["on" + type] = fn;
    }
  },

  removeEvent : function(el, type, fn) {
    if(typeof removeEventListener !== "undefined") {
      el.removeEventListener(type, fn, false);
    } else if(typeof detachEvent !== "undefined") {
      el.detachEvent("on" + type, fn);
    } else {
      el["on" + type] = null;
    }
  },

  getTarget : function(event) {
    if(typeof event.target !== "undefined") {
      return event.target;
    } else {
      return event.srcElement;
    }
  },

  preventDefault : function(event) {
    if(typeof event.preventDefault !== "undefined") {
      event.preventDefault();
    } else {
      event.returnValue = false;
    }
  }
};

Usage example:

var eventHandler = function(evt) {
  var target = eventUtility.getTarget(evt),
    tagName = target.tagName;

  if(evt.type === "click") {
    if(tagName === "A" || tagName === "BUTTON") {
      alert("You clicked on an A element, and the innerHTML is " + target.innerHTML + "!");
      eventUtility.preventDefault(evt);
    }
  } else if(evt.type === "mouseover" && tagName === "A") {
    alert("mouseovered " + target.innerHTML);
  }

};

eventUtility.addEvent(document, "click", eventHandler);
eventUtility.addEvent(document, "mouseover", eventHandler);

eventUtility.removeEvent(document, "mouseover", eventHandler);


Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn