JavaScriptのクロスブラウザイベントハンドリングの詳しい解釈_基礎知識

WBOY
リリース: 2016-05-16 15:45:35
オリジナル
1085 人が閲覧しました

1. イベントオブジェクトの取得について

FF は少し頑固で、arguments[0] のみをサポートし、window.even をサポートしません。今回は IE を責めるつもりはありませんが、イベントをウィンドウ属性として使用することは標準に反していますが、長年にわたってこの小さな問題が存在するのは FF だけであることはすでに黙認されています。したがって、クロスブラウザー イベント オブジェクトを取得するには 2 つの方法があります。

高麗人参入り:

getEvent : function(event){
  return event ? event : window.event;
  //return event || window.event;//或者更简单的方式
}
ログイン後にコピー

高麗人参なし:

function getEvent() {
  return arguments[0] ? arguments[0] : window.event;
  //return arguments[0] || window.event;//或者更简单的方式
}
ログイン後にコピー

1 つのメソッドについて特に説明する必要があります。HTML の DOM0 レベルのメソッド、パラメーターを含むイベント ハンドラーです。次のとおりです。

function handler(event){
  //do something
}
<!-- HTML的DOM0级方式 --><br /><button id="btn" onclick="handler(event);">按钮</button><br />
ログイン後にコピー

上記のメソッドはすべてのブラウザに対応していますが、HTML の DOM0 レベルのメソッドに依存する欠点は明らかなので、最初の 2 つのメソッドのように主流にはなっていません。また、JS の DOM0 レベルのメソッドにはパラメーター付きのイベント処理があります。 、次のように:

function handler(event){
  //do something
}
btn.onclick = handler;//JS的DOM0级方式
//btn.onclick = function(event){/*do something*/}//或者匿名函数,效果同上
ログイン後にコピー

この方法はすべてのブラウザと互換性があるわけではありません。[IE8-] はサポートされていません。IE9 は不明です。FF、Chrome はサポートしています。 HTML の DOM0 レベルのイベント処理と JS の DOM0 レベルのイベント処理は同等であるとずっと思っていましたが、今、多くの実験を行ったところ、この 2 つの

には違いがあることがわかりました。

2. イベントソースの取得について

event.srcElement は [IE8-] の唯一のメソッドです。IE9 は不明です。他のブラウザは標準のevent.target メソッドをサポートしています

3. イベントブロックのデフォルト動作について

event.preventDefault() は標準メソッドですが、IE 独自のメソッドはevent.returnValue = false;

ではサポートされていません。

4. イベントの拡散防止について

event.stopPropagation() は標準メソッドですが、IE は次のようにプレイしたいと考えています。 cancel はメソッドではなく属性であるため、ここでは特別な注意が必要です。標準とはかけ離れていて、使いやすいです

5. イベントハンドラーの追加と削除について

DOM レベル 0 メソッド

ele.onclick = handler;ele.onclick=null;最も古い方法

利点: すべてのブラウザと互換性があります

欠点: 同じイベントは 1 つのイベント ハンドラーしかバインド/バインド解除できません

DOM レベル 2 メソッド

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

ログイン後にコピー

IE モード: ele.attach/detachEvent('on'eventType, handler);

利点: 複数のイベント ハンドラーのバインド/バインド解除をサポート

欠点: 互換性の判断を行う必要があります。標準メソッドの最後のパラメータは、イベント キャプチャ フェーズ中にバインド/バインド解除するかどうかを示すため、IE はイベント キャプチャをサポートしていないため、3 番目のパラメータ

がないことに注意してください。

注: IE メソッドでは、メソッド名が標準と異なるだけでなく、パラメータのイベント タイプも on で追加する必要があります。追加しない場合、バインディングは無効になりますが、エラーは報告されません

6. クロスブラウザーイベントの処理

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

ログイン後にコピー

包括的な例

プロジェクトで jQuery などのライブラリが使用されていない場合、イベントを要素に簡単にバインドし、さまざまなブラウザと互換性を持たせるにはどうすればよいでしょうか?次の単純なユーティリティを考慮する必要があります。

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

ログイン後にコピー

使用例:

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

ログイン後にコピー


関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート