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 : myfunc2IE 7 전용입니다. 그에 따라 올바른 / 선호 방법을 수정하는 방법은 무엇입니까?


당신은 내가 이것을 말하는 것을 좋아하지 않을 수도 있지만 왜 그런 문제를 다루기 위해 프레임 워크를 사용하지 않습니까?
Pointy 2010-04-17

하지만이 경우에는 할 수 없습니다. 이걸 도와 주 시겠어요?
ginny

@ginny 내 대답을 살펴보십시오. 그 이상의 설명이 필요하면 알려주세요.
hitautodestruct

1
적어도 이벤트 를 등록 할 때마다 이벤트 모델을 테스트해서는 안됩니다 . 이것은 요소 , 이벤트 유형핸들러 를 전달하는 공통 함수로 쉽게 분리 될 수 있습니다 .
MrWhite

답변:


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은 이전 버전과의 호환성을 위해 두 가지 방법을 모두 지원합니다.

IE11에서 제거되었음을 지적한 Luke Puplett 에게 감사드립니다 attachEvent.

최소 크로스 브라우저 구현

Smitty가 권장 한대로 프레임 워크를 사용하지 않고 견고한 크로스 브라우저 구현 을 위해이 Dustin Diaz 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

13
addEventListenerIE9 +에서도 지원됩니다.
MrWhite

1
attachEvent는 IE11에서 제거되었으므로 IE를 감지하고이 API를 사용하는 코드는 이제 실패합니다. 나는 아직 이런 일이 발생하는 것을 보지 못했지만 IE11에서 IE10 에이전트 문자열을 스푸핑하면 스크립트 오류가 발생할 수 있음을 발견했습니다.
Luke Puplett 2013

@LukePuplett dustin diaz 구현은 브라우저 감지가 아닌 기능 감지를 기반으로합니다. 그것이 당신이 말하는 것입니까?
hitautodestruct 2013

7

아직이 토론에 참여하고 있고 그들이 원하는 답을 찾지 못한 사람 :
http://dustindiaz.com/rock-solid-addevent

이것은 프레임 워크 사용에 제한이있는 우리들에게 내가 찾은 가장 우아한 솔루션 중 하나입니다.

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.