addEventListener()/ attachEvent()の正しい使用法?


81

addEventListenerそれぞれattachEvent正しく使用する方法を知りたいですか?

window.onload = function (myFunc1) { /* do something */ }

function myFunc2() { /* do something */ }

if (window.addEventListener) {
  window.addEventListener('load', myFunc2, false);
} else if (window.attachEvent) {
  window.attachEvent('onload', myFunc2);
}

 // ...

または

function myFunc1() { /* do something */ }

if (window.addEventListener) {
  window.addEventListener('load', myFunc1, false);
} else if (window.attachEvent) {
  window.attachEvent('onload', myFunc1);
}

function myFunc2() { /* do something */ }

if (window.addEventListener) {
  window.addEventListener('load', myFunc2, false);
} else if (window.attachEvent) {
  window.attachEvent('onload', myFunc2);
}

 // ...

このクロスブラウザは安全ですか、それとも次のようなものを使用する方がよいでしょうか。

function myFunc1(){ /* do something */ }
function myFunc2(){ /* do something */ }
// ...

function addOnloadEvent(fnc){
  if ( typeof window.addEventListener != "undefined" )
    window.addEventListener( "load", fnc, false );
  else if ( typeof window.attachEvent != "undefined" ) {
    window.attachEvent( "onload", fnc );
  }
  else {
    if ( window.onload != null ) {
      var oldOnload = window.onload;
      window.onload = function ( e ) {
        oldOnload( e );
        window[fnc]();
      };
    }
    else
      window.onload = fnc;
  }
}

addOnloadEvent(myFunc1);
addOnloadEvent(myFunc2);
// ...

AND:Saymyfunc2はIE7専用です。それに応じて正しい/好ましい方法を変更する方法は?


私がこれを言うのは気に入らないかもしれませんが、なぜそのような問題に対処するためにフレームワークを使用しないのですか?
とがった2010

私はそうしますが、この場合はできません。それで、これを手伝ってくれませんか。
ginny 2010

@ginny私の答えを見てください。それ以上の説明が必要な場合はお知らせください。
hitautodestruct 2012年

1
少なくとも、あなたはイベントモデルをテストするべきではありません毎回あなたがイベントを登録します。これは、要素イベントタイプハンドラーを渡す共通の関数に簡単に分けることができます。
MrWhite 2012年

回答:


132

両方の使用法は似ていますが、どちらもイベントパラメータの構文が少し異なります。

addEventListener(mdnリファレンス):

すべての主要なブラウザ(FF、Chrome、Edge)でサポートされています

obj.addEventListener('click', callback, false);

function callback(){ /* do stuff */ }

イベントは、リストのためaddEventListener

attachEvent( msdnリファレンス):

IE 5-8 *でサポート

obj.attachEvent('onclick', callback);

function callback(){ /* do stuff */ }

イベントリストのためattachEvent

引数

どちらの方法でも、引数は次のとおりです。

  1. イベントタイプです。
  2. イベントがトリガーされたときに呼び出す関数です。
  3. addEventListenerのみ) trueの場合、ユーザーがキャプチャを開始することを希望していることを示します。

説明

どちらの方法も、イベントを要素にアタッチするという同じ目標を達成するために使用されます。
違いは、attachEvent古いトライデントレンダリングエンジン(IE5 + IE5-8 *)でのみ使用できaddEventListener、他のほとんどのブラウザー(FF、Webkit、Opera、IE9 +)で実装されているW3標準であるということです。

Diazソリューションでは得られない正規化を含む確実なクロスブラウザーイベントのサポートには、フレームワークを使用します。

* IE9-10は、下位互換性のために両方の方法をサポートしています。

IE11attachEventから削除されたことを指摘してくれたLukePuplettに感謝します。

最小限のクロスブラウザ実装

以下のようスミッティが推奨あなたはこれを見てとるべきであるダスティン・ディアスaddEventのフレームワークを使用せずに固体のクロスブラウザの実装のために:

function addEvent(obj, type, fn) {
  if (obj.addEventListener) {
    obj.addEventListener(type, fn, false);
  }
  else if (obj.attachEvent) {
    obj["e"+type+fn] = fn;
    obj[type+fn] = function() {obj["e"+type+fn](window.event);}
    obj.attachEvent("on"+type, obj[type+fn]);
  }
  else {
    obj["on"+type] = obj["e"+type+fn];
  }
}

addEvent( document, 'click', function (e) {
  console.log( 'document click' )
})


@CamiloMartin後でこのようなコメントがあったら、良い答えを出すことは常に価値があります、ありがとう:)
hitautodestruct 2012

13
addEventListenerIE9 +でもサポートされています。
MrWhite 2012年

1
attachEventはIE11で削除されたため、IEを検出してこのAPIを使用するコードは失敗します。これが発生するのはまだ見ていませんが、IE11からIE10エージェント文字列をスプーフィングするとスクリプトエラーが発生する可能性があることに気付きました。
Luke Puplett 2013年

@LukePuplettダスティン・ディーアスの実装は、ブラウザーの検出ではなく、機能の検出に基づいています。それはあなたが言及していることですか?
hitautodestruct 2013年

7

まだこの議論にぶつかり、チェックアウトを探していた答えが見つからない人は誰でも:http
//dustindiaz.com/rock-solid-addevent

これは、フレームワークの使用に制限がある私たちにとって最も洗練されたソリューションの1つです。

function addEvent(obj, type, fn) {

    if (obj.addEventListener) {
        obj.addEventListener(type, fn, false);
        EventCache.add(obj, type, fn);
    } else if (obj.attachEvent) {
        obj["e" + type + fn] = fn;
        obj[type + fn] = function() {
            obj["e" + type + fn](window.event);
        }
        obj.attachEvent("on" + type, obj[type + fn]);
        EventCache.add(obj, type, fn);
    } else {
        obj["on" + type] = obj["e" + type + fn];
    }

}

var EventCache = function() {

    var listEvents = [];
    return {
        listEvents: listEvents,
        add: function(node, sEventName, fHandler) {
            listEvents.push(arguments);
        },
        flush: function() {
            var i, item;

            for (i = listEvents.length - 1; i >= 0; i = i - 1) {
                item = listEvents[i];
                if (item[0].removeEventListener) {
                    item[0].removeEventListener(item[1], item[2], item[3]);
                };

                if (item[1].substring(0, 2) != "on") {
                    item[1] = "on" + item[1];
                };

                if (item[0].detachEvent) {
                    item[0].detachEvent(item[1], item[2]);
                };

                item[0][item[1]] = null;
            };
        }
    };
}();

addEvent(window, 'unload', EventCache.flush);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.