Heim  >  Artikel  >  Web-Frontend  >  Detaillierte Interpretation der browserübergreifenden Ereignisbehandlung von JavaScript_Grundkenntnisse

Detaillierte Interpretation der browserübergreifenden Ereignisbehandlung von JavaScript_Grundkenntnisse

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

1. Informationen zum Abrufen des Ereignisobjekts

FF ist etwas stur und unterstützt nur Argumente[0] und kein window.event. Diesmal mache ich dem IE wirklich keine Vorwürfe. Auch wenn die Verwendung von Ereignissen als Fensterattribut gegen die Norm verstößt, hat sich jeder mit der Existenz dieses kleinen Problems abgefunden. Nur FF war nach so vielen Jahren einzigartig. Daher gibt es zwei Möglichkeiten, browserübergreifende Ereignisobjekte abzurufen:

Mit Ginseng:

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

Ohne Ginseng:

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

Eine Methode muss insbesondere erklärt werden: HTMLs Methode auf DOM0-Ebene, Ereignishandler mit Parametern, wie folgt:

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

Die obige Methode ist mit allen Browsern kompatibel, aber die Nachteile der Verwendung der DOM0-Ebenenmethode von HTML liegen auf der Hand, sodass sie nicht wie die ersten beiden zu einer Mainstream-Methode geworden ist und die DOM0-Ebenenmethode von JS über eine Ereignisverarbeitung mit Parametern verfügt , wie folgt:

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

Diese Methode ist nicht mit allen Browsern kompatibel, [IE8-] wird nicht unterstützt, IE9 ist unbekannt, FF und Chrome unterstützen sie. Ich dachte immer, dass die Ereignisverarbeitung auf DOM0-Ebene von HTML und die Ereignisverarbeitung auf DOM0-Ebene von JS gleichwertig seien. Jetzt habe ich viele Experimente durchgeführt und festgestellt, dass es einen Unterschied zwischen den beiden gibt

2. Informationen zum Abrufen der Ereignisquelle

event.srcElement ist die einzige Methode für [IE8-], IE9 ist unbekannt, andere Browser unterstützen die Standardmethode event.target

3. Über das Standardverhalten von Blockierungsereignissen

event.preventDefault() ist eine Standardmethode, aber [IE8-] unterstützt sie nicht. Die IE-eigene Methode ist event.returnValue = false;

4. In Bezug auf die Eindämmung der Ausbreitung von Ereignissen

event.stopPropagation() ist eine Standardmethode. Er möchte hier so vorgehen: event.cancelBubble = true; Weit vom Standard entfernt und einfach zu bedienen

5. Informationen zum Hinzufügen und Entfernen von Event-Handlern

DOM-Level-0-Methode

ele.onclick = handler;ele.onclick=null;Der älteste Weg

Vorteile: Kompatibel mit allen Browsern

Nachteil: Das gleiche Ereignis kann nur einen Ereignishandler binden/entbinden

DOM-Level-2-Methode

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

Und IE-Modus: ele.attach/detachEvent(‘on’ eventType, handler);

Vorteile: Unterstützt das Binden/Entbinden mehrerer Event-Handler

Nachteile: Die Kompatibilität muss beurteilt werden. Es ist zu beachten, dass der letzte Parameter in der Standardmethode angibt, ob während der Ereigniserfassungsphase eine Bindung/Entbindung erfolgen soll. IE unterstützt keine Ereigniserfassung, daher gibt es keinen dritten Parameter

Hinweis: Bei der IE-Methode unterscheidet sich nicht nur der Methodenname vom Standard, sondern auch der Ereignistyp im Parameter muss mit „on“ hinzugefügt werden, andernfalls ist die Bindung ungültig, es wird jedoch kein Fehler gemeldet

6. Browserübergreifende Ereignisbehandlung

//跨浏览器的事件处理器添加方式
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;
    }
  }
};

Umfassendes Beispiel

Wenn im Projekt keine Bibliothek wie jQuery verwendet wird, wie kann man dann einfach Ereignisse an Elemente binden und sie mit verschiedenen Browsern kompatibel machen? Das folgende einfache Dienstprogramm sollte in Betracht gezogen werden.

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

Anwendungsbeispiel:

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


Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn