From ec53d27ce2baa0ec81655d486a8b04ff62d0e47b Mon Sep 17 00:00:00 2001 From: alattalatta Date: Mon, 13 Dec 2021 21:17:03 +0900 Subject: Rename EventTarget docs to md --- .../api/eventtarget/addeventlistener/index.html | 690 --------------------- .../web/api/eventtarget/addeventlistener/index.md | 690 +++++++++++++++++++++ .../web/api/eventtarget/dispatchevent/index.html | 75 --- .../ko/web/api/eventtarget/dispatchevent/index.md | 75 +++ .../ko/web/api/eventtarget/eventtarget/index.html | 70 --- files/ko/web/api/eventtarget/eventtarget/index.md | 70 +++ files/ko/web/api/eventtarget/index.html | 133 ---- files/ko/web/api/eventtarget/index.md | 133 ++++ .../api/eventtarget/removeeventlistener/index.html | 211 ------- .../api/eventtarget/removeeventlistener/index.md | 211 +++++++ 10 files changed, 1179 insertions(+), 1179 deletions(-) delete mode 100644 files/ko/web/api/eventtarget/addeventlistener/index.html create mode 100644 files/ko/web/api/eventtarget/addeventlistener/index.md delete mode 100644 files/ko/web/api/eventtarget/dispatchevent/index.html create mode 100644 files/ko/web/api/eventtarget/dispatchevent/index.md delete mode 100644 files/ko/web/api/eventtarget/eventtarget/index.html create mode 100644 files/ko/web/api/eventtarget/eventtarget/index.md delete mode 100644 files/ko/web/api/eventtarget/index.html create mode 100644 files/ko/web/api/eventtarget/index.md delete mode 100644 files/ko/web/api/eventtarget/removeeventlistener/index.html create mode 100644 files/ko/web/api/eventtarget/removeeventlistener/index.md (limited to 'files/ko') diff --git a/files/ko/web/api/eventtarget/addeventlistener/index.html b/files/ko/web/api/eventtarget/addeventlistener/index.html deleted file mode 100644 index 2e824e174b..0000000000 --- a/files/ko/web/api/eventtarget/addeventlistener/index.html +++ /dev/null @@ -1,690 +0,0 @@ ---- -title: EventTarget.addEventListener() -slug: Web/API/EventTarget/addEventListener -tags: - - API - - DOM - - Event Handlers - - Event Listener - - EventTarget - - JavaScript - - Method - - Reference -translation_of: Web/API/EventTarget/addEventListener ---- -
{{APIRef("DOM Events")}}
- -

{{domxref("EventTarget")}}의 addEventListener() 메서드는 지정한 이벤트가 대상에 전달될 때마다 호출할 함수를 설정합니다. 일반적인 대상은 {{domxref("Element")}}, {{domxref("Document")}}, {{domxref("Window")}}지만, {{domxref("XMLHttpRequest")}}와 같이 이벤트를 지원하는 모든 객체를 대상으로 지정할 수 있습니다.

- -

addEventListener()는 {{domxref("EventTarget")}}의 주어진 이벤트 유형에, {{domxref("EventListener")}}를 구현한 함수 또는 객체를 이벤트 처리기 목록에 추가해 작동합니다.

- -

구문

- -
target.addEventListener(type, listener[, options]);
-target.addEventListener(type, listener[, useCapture]);
-target.addEventListener(type, listener[, useCapture, wantsUntrusted {{Non-standard_inline}}]); // Gecko/Mozilla only
- -

매개변수

- -
-
type
-
반응할 이벤트 유형을 나타내는 대소문자 구분 문자열.
-
listener
-
지정된 타입의 이벤트가 발생했을 때, 알림({{domxref("Event")}} 인터페이스를 구현하는 객체)을 받는 객체입니다. {{domxref("EventListener")}} 인터페이스 또는 JavaScript function를 구현하는 객체여야만 합니다. 콜백 자체에 대한 자세한 내용은 {{anch("The event listener callback")}} 를 참조하세요.
-
options {{optional_inline}}
-
이벤트 리스너에 대한 특성을 지정하는 옵션 객체입니다. 사용 가능한 옵션은 다음과 같습니다 : -
    -
  • capture: DOM 트리의 하단에 있는 EventTarget 으로 전송하기 전에, 등록된 listener 로 이 타입의 이벤트의 전송여부를 나타내는 {{jsxref("Boolean")}} 입니다.
  • -
  • once: 리스너를 추가한 후 한 번만 호출되어야 함을 나타내는 {{jsxref("Boolean")}}입니다. true이면 호출할 때 listener 가 자동으로 삭제됩니다.
  • -
  • passive: true일 경우, listener에서 지정한 함수가 {{domxref("Event.preventDefault", "preventDefault()")}}를 호출하지 않음을 나타내는 {{jsxref("Boolean")}}입니다. passive listener 가 preventDefault()를 호출하면 user agent는 콘솔 경고를 생성하는 것 외의 작업은 수행하지 않습니다. 자세한 내용은 {{anch("Improving scrolling performance with passive listeners")}} 를 참조하세요.
  • -
  • {{non-standard_inline}} mozSystemGroup: listener를 시스템 그룹에 추가해야함을 나타내는 {{jsxref("Boolean")}} 입니다. 오직 XBL 혹은 파이어폭스 브라우저의 {{glossary("chrome")}}에서 실행되는 코드에서만 사용할 수 있습니다.
  • -
-
-
useCapture {{optional_inline}}
-
DOM 트리의 하단에 있는 EventTarget 으로 전송하기 전에, 등록된 listener 로 이 타입의 이벤트의 전송여부를 나타내는 {{jsxref("Boolean")}} 입니다. 트리에서 위쪽으로 버블링되는 이벤트는 캡처를 사용하도록, 지정된 listener를 트리거하지 않습니다. 이벤트 버블링과 캡쳐는 두 요소(엘리먼트)가 해당 이벤트에 대한 핸들(함수)를 등록한 경우, 다른 요소 내에 중첩된 요소에서 발생하는 이벤트를 전파하는 두 가지 방법 입니다. 이벤트 전파 모드는 요소가 이벤트를 수신하는 순서를 판별합니다. 자세한 설명은 DOM Level 3 Events 과 JavaScript Event order 를 참조하세요. 값을 지정하지 않으면, useCapture 의 기본값은 false 입니다.
-
-
참고: 이벤트 타겟에 연결된 이벤트 리스너의 경우, 이벤트는 캡쳐링과 버블링 단계가 아니라 타겟 단계에 있습니다. 타겟 단계의 이벤트는 useCapture 매개변수(파라미터)와 상관없이, 그들이 등록된 순서대로 요소의 모든 리스너를 트리거합니다.
- -
참고: useCapture 가 항상 선택사항인 것은 아닙니다. 가장 광범위한 브라우저 호환성을 위해 포함시키는 것이 좋습니다.
-
-
wantsUntrusted {{Non-standard_inline}}
-
파이어폭스(겍코) 명세의 매개변수 입니다. true의 경우, 리스너는 웹 컨텐츠에 의해 dispatch되는 합성 이벤트를 수신합니다. (기본값은 {{glossary("chrome")}} 브라우저의 경우 false , 보통의 웹 페이지에서는 true입니다.) 이 매개 변수는 브라우저 자체 뿐만 아니라, 에드온에게도 유용합니다.
-
- -

Usage notes

- -

이벤트 리스너 콜백

- -

이벤트 리스너는 콜백 함수로 지정할 수 있습니다. 또는 {{domxref("EventListener.handleEvent", "handleEvent()")}} 메서드가 콜백 함수 역할을 하는 {{domxref("EventListener")}}를 구현하는 객체로 지정할 수 있습니다.

- -

콜백 함수 자체는 handleEvent() 메서드와 동일한 매개 변수와 반환값을 가집니다. 즉, 콜백은 단일 매개 변수를 허용합니다: 발생한 이벤트를 설명하는 {{domxref("Event")}}에 기반한 객체이며, 아무것도 반환하지 않습니다.

- -

예를들어 {{event("fullscreenchange")}} 와 {{event("fullscreenerror")}}를 처리하는데 사용할 수 있는 이벤트 핸들러 콜백은 다음과 같습니다:

- -
function eventHandler(event) {
-  if (event.type == 'fullscreenchange') {
-    /* handle a full screen toggle */
-  } else /* fullscreenerror */ {
-    /* handle a full screen toggle error */
-  }
-}
- -

옵션 지원을 안전하게 감지

- -

이전 버전의 DOM 명세에선, addEventListener()의 세 번째 매개 변수는 캡쳐의 사용여부를 나타내는 Boolean값 이었습니다. 시간이 지남에 따라 더 많은 옵션이 필요하다는 것이 분명 해졌습니다. 함수에 매개 변수를 추가하는 대신 (옵션값을 처리할 때 엄청나게 복잡한 작업), 세 번째 매개 변수는 다양한 속성을 포함 할 수 있는 객체로 변경되었습니다. 이 객체는 이벤트 리스너를 제거하는 프로세스를 구성하는 옵션값을 정의할 수 있습니다.

- -

지난 버전의 브라우저(뿐만 아니라 너무 오래된 브라우저)에서는 여전히 세 번째 매개 변수가 Boolean 이라고 가정하고 시나리오를 지능적으로 처리할 코드를 작성해야 합니다. 관심있는 각 옵션에 대해 기능 감지를 사용하여 이 작업을 수행할 수 있습니다.

- -

예를들어서, passive 옵션을 확인하려면 다음과 같이 하세요 :

- -
var passiveSupported = false;
-
-try {
-  var options = {
-    get passive() { // This function will be called when the browser
-                    //     attempts to access the passive property.
-      passiveSupported = true;
-    }
-  };
-
-  window.addEventListener("test", options, options);
-  window.removeEventListener("test", options, options);
-} catch(err) {
-  passiveSupported = false;
-}
- -

이렇게 하면 passive 속성(프로퍼티)에 대한 getter함수를 사용하여 options 객체가 만들어집니다; get을 호출 할 경우 gtter는 플래그 passiveSupportedtrue로 설정합니다. 즉, 브라우저가 options 객체의 passive 속성 값을 검사하면 passiveSupportedtrue로 설정됩니다; 그렇지 않으면 false가 유지됩니다. 그리고 addEventListener()를 호출하여 가짜 이벤트 핸들러를 설정합니다. 해당 옵션을 지정하여 브라우저가 객체를 세 번째 매개 변수로 인식하면 옵션을 확인합니다. 그런 다음 removeEventListener() 를 호출하여 스스로 정리합니다. (handleEvent()는 호출되지 않은 이벤트 리스너에서는 무시됩니다.) 

- -

이 방법으로 지원되는 옵션이 있는지 확인할 수 있습니다. 위와 비슷한 코드를 사용하여 해당 옵션에 대한 getter를 추가하기 만하면됩니다.

- -

그런 다음 문제의 옵션을 사용하는 실제 이벤트 리스너를 만들려면 다음과 같이 쓸 수 있습니다:

- -
someElement.addEventListener("mouseup", handleMouseUp, passiveSupported
-                               ? { passive: true } : false);
- -

여기에서는 {{event("mouseup")}} 이벤트에 대한 리스너를 someElement요소에 추가합니다.  새 번째 매개변수의 경우 passiveSupported가 true면, options 객체를 passive : true 로 설정합니다; 그렇지 않으면, 우리는 Boolean을 전달해야 함올 알고있습니다. useCapture 매개변수의 값으로 false 를 전달합니다.

- -

원하는 경우 Modernizr 혹은 Detect It 과 같은 서드파티 라이브러리를 사용하여 이러한 테스트를 수행할 수 있습니다.

- -

Web Incubator Community Group의 EventListenerOptions에 대한 기사에서 더 많은 것을 배울 수 있습니다.

- -

예제

- -

간단한 리스너 추가

- -

이 예제는 addEventListener() 를 사용하여 요소에 대한 마우스 클릭을 감지하는 방법을 보여줍니다.

- -

HTML

- -
<table id="outside">
-    <tr><td id="t1">one</td></tr>
-    <tr><td id="t2">two</td></tr>
-</table>
-
- -

JavaScript

- -
// Function to change the content of t2
-function modifyText() {
-  var t2 = document.getElementById("t2");
-  if (t2.firstChild.nodeValue == "three") {
-    t2.firstChild.nodeValue = "two";
-  } else {
-    t2.firstChild.nodeValue = "three";
-  }
-}
-
-// add event listener to table
-var el = document.getElementById("outside");
-el.addEventListener("click", modifyText, false);
-
- -

이 코드에서, modifyText() 는 addEventListener()를 사용하여 등록된 click 이벤트에 대한 리스너입니다. 테이블의 아무곳이나 클릭하더라도, 핸들러에서 버블링되고 modifyText() 가 실행됩니다.

- -

결과

- -

{{EmbedLiveSample('간단한_리스너_추가')}}

- -

익명 함수와 이벤트 리스너

- -

여기서는 익명 함수를 사용하여 매개 변수를 이벤트 리스너에 전달하는 방법을 살펴보겠습니다.

- -

HTML

- -
<table id="outside">
-    <tr><td id="t1">one</td></tr>
-    <tr><td id="t2">two</td></tr>
-</table>
- -

JavaScript

- -
// Function to change the content of t2
-function modifyText(new_text) {
-  var t2 = document.getElementById("t2");
-  t2.firstChild.nodeValue = new_text;
-}
-
-// Function to add event listener to table
-var el = document.getElementById("outside");
-el.addEventListener("click", function(){modifyText("four")}, false);
-
- -

리스너는 코드를 캡슐화 하는 익명 함수입니다. 이 익명의 함수는 실제로 이벤트에 응답하는 책임이 있는 modifyText() 함수에 매개변수를 전달 할 수 있습니다.

- -

Result

- -

{{EmbedLiveSample('익명_함수와_이벤트_리스너')}}

- -

화살표 함수와 이벤트 리스너

- -

이 예제는 화살표 함수를 사용하여 구현된 간단한 이벤트 리스너를 보여줍니다. 

- -

HTML

- -
<table id="outside">
-    <tr><td id="t1">one</td></tr>
-    <tr><td id="t2">two</td></tr>
-</table>
- -

JavaScript

- -
// Function to change the content of t2
-function modifyText(new_text) {
-  var t2 = document.getElementById("t2");
-  t2.firstChild.nodeValue = new_text;
-}
-
-// Add event listener to table with an arrow function
-var el = document.getElementById("outside");
-el.addEventListener("click", () => { modifyText("four"); }, false);
-
- -

결과

- -

{{EmbedLiveSample('화살표_함수와_이벤트_리스너')}}

- -

화살표 함수와 익명 함수는 유사하지만 서로 다른 this바인딩을 가집니다. 익명(모든 전통적인 자바스크립트 함수)는 그들 자신의 this 바인딩을 만들지만, 화살표 함수는 포함하고 있는 함수의 this바인딩을 상속합니다.

- -

즉, 화살표 함수를 사용할 때 포함하고 있는 함수에서 사용중인 변수 및 상수를 이벤트 핸들러에서 사용할 수 있습니다.

- -

옵션의 사용 예제

- -

HTML

- -
<div class="outer">
-    outer, once & none-once
-    <div class="middle" target="_blank">
-        middle, capture & none-capture
-        <a class="inner1" href="https://www.mozilla.org" target="_blank">
-            inner1, passive & preventDefault(which is not allowed)
-        </a>
-        <a class="inner2" href="https://developer.mozilla.org/" target="_blank">
-            inner2, none-passive & preventDefault(not open new page)
-        </a>
-    </div>
-</div>
-
- -

CSS

- -
    .outer, .middle, .inner1, .inner2 {
-        display:block;
-        width:520px;
-        padding:15px;
-        margin:15px;
-        text-decoration:none;
-    }
-    .outer{
-        border:1px solid red;
-        color:red;
-    }
-    .middle{
-        border:1px solid green;
-        color:green;
-        width:460px;
-    }
-    .inner1, .inner2{
-        border:1px solid purple;
-        color:purple;
-        width:400px;
-    }
-
- -

JavaScript

- -
    let outer  = document.getElementsByClassName('outer') [0];
-    let middle = document.getElementsByClassName('middle')[0];
-    let inner1 = document.getElementsByClassName('inner1')[0];
-    let inner2 = document.getElementsByClassName('inner2')[0];
-
-    let capture = {
-        capture : true
-    };
-    let noneCapture = {
-        capture : false
-    };
-    let once = {
-        once : true
-    };
-    let noneOnce = {
-        once : false
-    };
-    let passive = {
-        passive : true
-    };
-    let nonePassive = {
-        passive : false
-    };
-
-
-    outer.addEventListener('click', onceHandler, once);
-    outer.addEventListener('click', noneOnceHandler, noneOnce);
-    middle.addEventListener('click', captureHandler, capture);
-    middle.addEventListener('click', noneCaptureHandler, noneCapture);
-    inner1.addEventListener('click', passiveHandler, passive);
-    inner2.addEventListener('click', nonePassiveHandler, nonePassive);
-
-    function onceHandler(event)
-    {
-        alert('outer, once');
-    }
-    function noneOnceHandler(event)
-    {
-        alert('outer, none-once, default');
-    }
-    function captureHandler(event)
-    {
-        //event.stopImmediatePropagation();
-        alert('middle, capture');
-    }
-    function noneCaptureHandler(event)
-    {
-        alert('middle, none-capture, default');
-    }
-    function passiveHandler(event)
-    {
-        // Unable to preventDefault inside passive event listener invocation.
-        event.preventDefault();
-        alert('inner1, passive, open new page');
-    }
-    function nonePassiveHandler(event)
-    {
-        event.preventDefault();
-        //event.stopPropagation();
-        alert('inner2, none-passive, default, not open new page');
-    }
-
- -

Result

- -

옵션이 어떻게 작동하는지 보려면 각각 outer, middle, inner 컨테이너를 클릭해 보세요.

- -

{{ EmbedLiveSample('옵션의_사용_예제', 600, 310, '', 'Web/API/EventTarget/addEventListener') }}

- -

options 객체에서 특정 값을 사용하기 전에, 모든 브라우저의 모든 버전이 지원하는 것은 아니므로, 사용자의 브라우저가 해당 기능을 지원하는지 확인하는 것이 좋습니다. 자세한 내용은 {{anch("Safely detecting option support")}} 을 참조하세요.

- -

Other notes

- -

addEventListener를 사용하나요?

- -

addEventListener() 는 W3C 에서 지정한 DOM에 이벤트 리스너를 등록하는 방법입니다. 장점은 다음과 같습니다:

- - - -

대안으로, 이벤트 리스너를 등록하는 오래된 방법은 아래에 설명되어 있습니다.

- -

이벤트 전달중에 리스너 추가

- -

{{domxref("EventListener")}} 가 이벤트 처리중에 {{domxref("EventTarget")}}에 추가되었다면, 그 이벤트는 리스너를 트리거하지 않습니다. 그러나 동일한 리스너는 버블링 단계와 같은 이벤트 흐름의 나중 단계에서 트리거 될 수 있습니다. 

- -

다수의 동일한 이벤트 리스너

- -

만약 동일한 여러개의 EventListener 가 동일한 매개변수(parameter)로 동일한 EventTarget 에 등록되었다면, 중복된 항목(인스턴스)들은 버려집니다. EventListener는 두번 호출되지 않으며 {{domxref("EventTarget.removeEventListener", "removeEventListener()")}} 메서드를 사용해 직접 제거할 필요가 없습니다. 그러나 익명 함수를 핸들러로 사용할 때, 루프를 도는 경우가 있습니다. 이 경우 단순히 반복적으로 호출하는 동일한 소스 코드를 사용하여 이벤트를 등록하더라도, 익명 함수는 동일하지 않고 이 때문에 리스너 또한 동일하지 않습니다. 이와 같은 경우 동일한 함수를 반복적으로 정의하는 것이 더 문제가 될 수 있습니다. (아래의 메모리 문제를 참조하세요.)

- -

핸들러 내부의 this 값

- -

유사한 요소 집합에 대한 일반적인 핸들러를 사용할 때와 같이, 이벤트 핸들러가 동작한 엘리먼트를 참조하는것이 좋습니다.

- -

addEventListener() 를 사용하여 핸들러 함수를 요소에 연결하면, 핸들러 내부의 this 값은 요소에 대한 참조입니다. 이것은 핸들러에 전달 된 이벤트 인수(아규먼트)의 currentTarget 속성(프로퍼티)값과 같습니다.

- -
my_element.addEventListener('click', function (e) {
-  console.log(this.className)           // logs the className of my_element
-  console.log(e.currentTarget === this) // logs `true`
-})
-
- -

다시 말해, 화살표 함수에는 this 컨텍스트가 없습니다.

- -
my_element.addEventListener('click', (e) => {
-  console.log(this.className)           // WARNING: `this` is not `my_element`
-  console.log(e.currentTarget === this) // logs `false`
-})
- -

HTML 소스의 요소(element)에 이벤트 핸들러(예: onclick)가 지정된 경우, 속성 값(attribute value)의 자바스크립트 코드는 효과적으로 addEventListener() 에 따라  this값을 바인드하는 핸들러 함수로 래핑됩니다. 코드 내에서 this가 발생하면 요소에 대한 참조를 나타냅니다.

- -
<table id="my_table" onclick="console.log(this.id);"><!-- `this` refers to the table; logs 'my_table' -->
-  ...
-</table>
-
- -

속성 값(attribute value)의 코드에 의해 호출 된 함수 내부의 this 는 표준 규칙들에 따라 동작합니다. 다음은 그 예입니다.

- -
<script>
-  function logID() { console.log(this.id); }
-</script>
-<table id="my_table" onclick="logID();"><!-- when called, `this` will refer to the global object -->
-  ...
-</table>
-
-
- -

logID() 내의 this 값은 {{domxref("Window")}} 전역 객체에 대한 참조입니다. (혹은 strict mode 의 경우 undefined입니다.)

- -

bind()를 사용하여 this지정하기

- -

Function.prototype.bind() 메서드를 사용하면 지정한 함수에 대한 모든 호출에 대해 this 값으로 사용해야 하는 값을 지정할 수 있습니다. 이를 이용하여 함수가 호출 된 컨텍스트에 따라 this 가 무엇인지 명확하지 않은 문제를 쉽게 우회할 수 있습니다. 그러나 나중에 제거할 수 있도록, 주위에 리스너에 대한 참조를 유지해야 합니다.

- -

다음은 bind() 를 사용한, 사용하지 않은 예제입니다 :

- -
var Something = function(element) {
-  // |this| is a newly created object
-  this.name = 'Something Good';
-  this.onclick1 = function(event) {
-    console.log(this.name); // undefined, as |this| is the element
-  };
-  this.onclick2 = function(event) {
-    console.log(this.name); // 'Something Good', as |this| is bound to newly created object
-  };
-  element.addEventListener('click', this.onclick1, false);
-  element.addEventListener('click', this.onclick2.bind(this), false); // Trick
-}
-var s = new Something(document.body);
-
- -

또 다른 해결책은 handleEvent()라는 특수 함수를 사용하여 어떤 이벤트를 캐치 하는것입니다 :

- -
var Something = function(element) {
-  // |this| is a newly created object
-  this.name = 'Something Good';
-  this.handleEvent = function(event) {
-    console.log(this.name); // 'Something Good', as this is bound to newly created object
-    switch(event.type) {
-      case 'click':
-        // some code here...
-        break;
-      case 'dblclick':
-        // some code here...
-        break;
-    }
-  };
-
-  // Note that the listeners in this case are |this|, not this.handleEvent
-  element.addEventListener('click', this, false);
-  element.addEventListener('dblclick', this, false);
-
-  // You can properly remove the listeners
-  element.removeEventListener('click', this, false);
-  element.removeEventListener('dblclick', this, false);
-}
-var s = new Something(document.body);
-
- -

this에 대한 참조를 처리하는 또 다른 방법은, EventListener 에 함수를 전달하는 것입니다. 이 함수는 접근을 필요로 하는 필드가 들어있는, 객체의 메서드를 호출하는 함수입니다:

- -
class SomeClass {
-
-  constructor() {
-    this.name = 'Something Good';
-  }
-
-  register() {
-    var that = this;
-    window.addEventListener('keydown', function(e) {return that.someMethod(e);});
-  }
-
-  someMethod(e) {
-    console.log(this.name);
-    switch(e.keyCode) {
-      case 5:
-        // some code here...
-        break;
-      case 6:
-        // some code here...
-        break;
-    }
-  }
-
-}
-
-var myObject = new SomeClass();
-myObject.register();
- -

오래된 인터넷 익스플로러와 attachEvent

- -

인터넷 익스플로러 9 이전 버전에서는, 표준 addEventListener() 가 아닌 {{domxref("EventTarget.attachEvent", "attachEvent()")}}를 사용해야 합니다. IE의 경우 위의 예제를 다음과 같이 수정합니다:

- -
if (el.addEventListener) {
-  el.addEventListener('click', modifyText, false);
-} else if (el.attachEvent)  {
-  el.attachEvent('onclick', modifyText);
-}
-
- -

attachEvent()의 단점은 다음과 같습니다: this의 값이 이벤트가 바인드되어 있는 요소 대신에, window객체에 대한 참조가 됩니다.

- -

attachEvent() 메서드는 onresize 이벤트와 쌍을 이루어 웹 페이지의 특정 요소의 크기가 리사이징 되는 시점을 감지할 수 있습니다. mselementresize 라는 독점적인 이벤트는, 이벤트 핸들러를 등록하는 addEventListener 메서드와 함께 사용할 때 onresize와 유사한 기능을 제공하여, 특정 HTML 요소의 크기를 리사이징 할 때 실행됩니다.

- -

호환성

- -

스크립트 시작 부분에 다음 코드를 사용하여, 인터넷 익스플로러 8 에서 지원하지 않는 addEventListener(), removeEventListener(), {{domxref("Event.preventDefault()")}}, {{domxref("Event.stopPropagation()")}} 을 해결할 수 있습니다. 이 코드는 handleEvent()와 {{event("DOMContentLoaded")}} 이벤트에 대한 사용을 지원합니다.

- -
-

참고: IE8 에서는 useCapture를 지원할 수 있는 다른 방법이 없습니다. 다음의 코드는 IE8 지원만 추가합니다. 이 IE8 폴리필은 표준 모드에서만 작동합니다: doctype 선언이 필요합니다.

-
- -
(function() {
-  if (!Event.prototype.preventDefault) {
-    Event.prototype.preventDefault=function() {
-      this.returnValue=false;
-    };
-  }
-  if (!Event.prototype.stopPropagation) {
-    Event.prototype.stopPropagation=function() {
-      this.cancelBubble=true;
-    };
-  }
-  if (!Element.prototype.addEventListener) {
-    var eventListeners=[];
-
-    var addEventListener=function(type,listener /*, useCapture (will be ignored) */) {
-      var self=this;
-      var wrapper=function(e) {
-        e.target=e.srcElement;
-        e.currentTarget=self;
-        if (typeof listener.handleEvent != 'undefined') {
-          listener.handleEvent(e);
-        } else {
-          listener.call(self,e);
-        }
-      };
-      if (type=="DOMContentLoaded") {
-        var wrapper2=function(e) {
-          if (document.readyState=="complete") {
-            wrapper(e);
-          }
-        };
-        document.attachEvent("onreadystatechange",wrapper2);
-        eventListeners.push({object:this,type:type,listener:listener,wrapper:wrapper2});
-
-        if (document.readyState=="complete") {
-          var e=new Event();
-          e.srcElement=window;
-          wrapper2(e);
-        }
-      } else {
-        this.attachEvent("on"+type,wrapper);
-        eventListeners.push({object:this,type:type,listener:listener,wrapper:wrapper});
-      }
-    };
-    var removeEventListener=function(type,listener /*, useCapture (will be ignored) */) {
-      var counter=0;
-      while (counter<eventListeners.length) {
-        var eventListener=eventListeners[counter];
-        if (eventListener.object==this && eventListener.type==type && eventListener.listener==listener) {
-          if (type=="DOMContentLoaded") {
-            this.detachEvent("onreadystatechange",eventListener.wrapper);
-          } else {
-            this.detachEvent("on"+type,eventListener.wrapper);
-          }
-          eventListeners.splice(counter, 1);
-          break;
-        }
-        ++counter;
-      }
-    };
-    Element.prototype.addEventListener=addEventListener;
-    Element.prototype.removeEventListener=removeEventListener;
-    if (HTMLDocument) {
-      HTMLDocument.prototype.addEventListener=addEventListener;
-      HTMLDocument.prototype.removeEventListener=removeEventListener;
-    }
-    if (Window) {
-      Window.prototype.addEventListener=addEventListener;
-      Window.prototype.removeEventListener=removeEventListener;
-    }
-  }
-})();
- -

이벤트 리스너를 등록하는 고전적인 방법

- -

addEventListener()는 DOM 2 Events 명세와 함께 도입되었습니다. 그 전에는 다음과 같이 이벤트 리스너를 등록했습니다:

- -
// Passing a function reference ? do not add '()' after it, which would call the function!
-el.onclick = modifyText;
-
-// Using a function expression
-element.onclick = function() {
-  // ... function logic ...
-};
-
- -

This 이 메서드는 요소의 기존 click 이벤트 리스너가 있을 경우에, 그것을 대체합니다. blur (onblur) 및 keypress (onkeypress) 와 같은 다른 이벤트 및 이벤트 핸들러도 비슷하게 작동합니다.

- -

이것은 본질적으로 {{glossary("DOM", "DOM 0")}}의 일부였기 때문에, 이벤트 리스너를 추가하는데 매우 광범위하게 지원되며 특별한 크로스 브라우징 코드가 필요하지 않습니다. 이것은 일반적으로 addEventListener()의 추가 기능이 필요하지 않으면, 이벤트 리스너를 동적으로 등록하는데 사용합니다.

- -

메모리 이슈

- -
var i;
-var els = document.getElementsByTagName('*');
-
-// Case 1
-for(i=0 ; i<els.length ; i++){
-  els[i].addEventListener("click", function(e){/*do something*/}, false);
-}
-
-// Case 2
-function processEvent(e){
-  /*do something*/
-}
-
-for(i=0 ; i<els.length ; i++){
-  els[i].addEventListener("click", processEvent, false);
-}
-
- -

위의 첫 번째 경우, 루프의 각 반복마다 새로운 익명 핸들러 함수가 생성됩니다. 두 번째 경우에는 이전에 선언한 동일한 함수를 이벤트 핸들러로 사용하므로, 메모리 소비가 줄어듭니다. 또한 첫 번째 경우에는 removeEventListener()를 호출할 수 없습니다. 익명 함수에 대한 참조가 유지되지 않기 때문입니다.(루프가 생성할 수 있는 여러개의 익명 함수 중 하나에 보관되지 않습니다) 두 번째 경우에는 processEvent가 함수 참조이기 때문에, myElement.removeEventListener("click", processEvent, false)를 수행할 수 있습니다.

- -

사실, 메모리 소비와 관련하여, 함수 참조를 유지하는 것은 진짜 문제가 아닙니다. 오히려 정적 함수 참조를 유지하는 것이 부족합니다. 아래의 두 경우(3,4번째 케이스) 모두 함수 참조가 유지되지만, 각 반복에서 재정의 되므로 정적이 아닙니다. 세 번째 경우에는 익명 함수에 대한 참조가, 반복될 때 마다 다시 할당됩니다. 네 번째 경우에는 전체 함수 정의가 변경되지 않지만, 새로운 것처럼(컴파일러에 의해 [[promoted]]되지 않는 한) 반복적으로 정의되고 있고 그래서 정적이지 않습니다. 따라서 간단하게 [[여러개의 동일한 이벤트 리스너]]인 것처럼 보이지만, 두 경우 모두 각 반복은 핸들러 함수에 대한 고유한 참조로 새로운 리스너를 생성합니다. 그러나 함수 정의 자체는 변경되지 않으므로, 모든 중복 리스너에 대해 같은 함수가 여전히 호출될 수 있습니다.(특히 코드가 최적화되는 경우)

- -

또한 두 경우 모두 함수 참조가 유지되었지만, 각 가산에 대해 반복적으로 재정의 되었습니다. 위에서 사용했던 remove 문(statement)으로는 리스너를 제거할 수 있지만, 마지막으로 추가한 리스너만 제거됩니다.

- -
// For illustration only: Note "MISTAKE" of [j] for [i] thus causing desired events to all attach to SAME element
-
-// Case 3
-for(var i=0, j=0 ; i<els.length ; i++){
-  /*do lots of stuff with j*/
-  els[j].addEventListener("click", processEvent = function(e){/*do something*/}, false);
-}
-
-// Case 4
-for(var i=0, j=0 ; i<els.length ; i++){
-  /*do lots of stuff with j*/
-  function processEvent(e){/*do something*/};
-  els[j].addEventListener("click", processEvent, false);
-}
- -

passive 리스너로 스크롤링 성능 향상

- -

명세에 따르면, passive option의 기본값은 항상 false 입니다. 그러나 이것은 이벤트 리스너가 특정 터치 이벤트를 처리하는 경우(다른 이벤트를 포함하여), 스크롤을 처리하는 동안 브라우저의 메인 스레드를 차단하기 때문에, 스크롤 처리 시 성능이 크게 저하될 수 있습니다.

- -

이러한 문제를 방지하기 위하여, 일부 브라우저(특히 크롬과 파이어폭스)는 document-level nodes인 {{domxref("Window")}}, {{domxref("Document")}}, {{domxref("Document.body")}}의 경우 {{event("touchstart")}} 와{{event("touchmove")}} 이벤트에 대해 passive 옵션의 기본값을 true로 변경했습니다. 이렇게 하면 이벤트 리스너가 호출되지 않으므로, 사용자가 스크롤 하는 동안 페이지 렌더링을 차단할 수 없습니다.

- -
-

참고: 이 변경된 동작을 구현하는 브라우저(혹은 브라우저의 버전)을 알아야 할 경우 아래의 호환성 표를 참조하세요.

-
- -

다음과 같이 passive의 값을 명시적으로 false로 설정을 오버라이드 하여 이 동작을 무시할 수 있습니다:

- -
/* Feature detection */
-var passiveIfSupported = false;
-
-try {
-  window.addEventListener("test", null, Object.defineProperty({}, "passive", { get: function() { passiveIfSupported = { passive: true }; } }));
-} catch(err) {}
-
-window.addEventListener('scroll', function(event) {
-  /* do something */
-  // can't use event.preventDefault();
-}, passiveIfSupported );
-
- -

addEventListener()에 대한 options 매개변수를 지원하지 않는 이전 브라우저에서는, feature detection를 사용하지 않고는 useCapture 인수를 사용하지 못하도록 해야 합니다.

- -

{{event("scroll")}} 이벤트의 기본 passive 값에 대해 걱정할 필요는 없습니다. 취소할 수 없기 때문에, 이벤트 리스너는 페이지 렌더링을 차단할 수 없습니다.

- -

명세

- - - - - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName("DOM WHATWG", "#dom-eventtarget-addeventlistener", "EventTarget.addEventListener()")}}{{Spec2("DOM WHATWG")}} 
{{SpecName("DOM4", "#dom-eventtarget-addeventlistener", "EventTarget.addEventListener()")}}{{Spec2("DOM4")}} 
{{SpecName("DOM2 Events", "#Events-EventTarget-addEventListener", "EventTarget.addEventListener()")}}{{Spec2("DOM2 Events")}}Initial definition
- -

브라우저 호환성

- - - -

{{Compat("api.EventTarget.addEventListener", 3)}}

- -

같이 보기

- - diff --git a/files/ko/web/api/eventtarget/addeventlistener/index.md b/files/ko/web/api/eventtarget/addeventlistener/index.md new file mode 100644 index 0000000000..2e824e174b --- /dev/null +++ b/files/ko/web/api/eventtarget/addeventlistener/index.md @@ -0,0 +1,690 @@ +--- +title: EventTarget.addEventListener() +slug: Web/API/EventTarget/addEventListener +tags: + - API + - DOM + - Event Handlers + - Event Listener + - EventTarget + - JavaScript + - Method + - Reference +translation_of: Web/API/EventTarget/addEventListener +--- +
{{APIRef("DOM Events")}}
+ +

{{domxref("EventTarget")}}의 addEventListener() 메서드는 지정한 이벤트가 대상에 전달될 때마다 호출할 함수를 설정합니다. 일반적인 대상은 {{domxref("Element")}}, {{domxref("Document")}}, {{domxref("Window")}}지만, {{domxref("XMLHttpRequest")}}와 같이 이벤트를 지원하는 모든 객체를 대상으로 지정할 수 있습니다.

+ +

addEventListener()는 {{domxref("EventTarget")}}의 주어진 이벤트 유형에, {{domxref("EventListener")}}를 구현한 함수 또는 객체를 이벤트 처리기 목록에 추가해 작동합니다.

+ +

구문

+ +
target.addEventListener(type, listener[, options]);
+target.addEventListener(type, listener[, useCapture]);
+target.addEventListener(type, listener[, useCapture, wantsUntrusted {{Non-standard_inline}}]); // Gecko/Mozilla only
+ +

매개변수

+ +
+
type
+
반응할 이벤트 유형을 나타내는 대소문자 구분 문자열.
+
listener
+
지정된 타입의 이벤트가 발생했을 때, 알림({{domxref("Event")}} 인터페이스를 구현하는 객체)을 받는 객체입니다. {{domxref("EventListener")}} 인터페이스 또는 JavaScript function를 구현하는 객체여야만 합니다. 콜백 자체에 대한 자세한 내용은 {{anch("The event listener callback")}} 를 참조하세요.
+
options {{optional_inline}}
+
이벤트 리스너에 대한 특성을 지정하는 옵션 객체입니다. 사용 가능한 옵션은 다음과 같습니다 : +
    +
  • capture: DOM 트리의 하단에 있는 EventTarget 으로 전송하기 전에, 등록된 listener 로 이 타입의 이벤트의 전송여부를 나타내는 {{jsxref("Boolean")}} 입니다.
  • +
  • once: 리스너를 추가한 후 한 번만 호출되어야 함을 나타내는 {{jsxref("Boolean")}}입니다. true이면 호출할 때 listener 가 자동으로 삭제됩니다.
  • +
  • passive: true일 경우, listener에서 지정한 함수가 {{domxref("Event.preventDefault", "preventDefault()")}}를 호출하지 않음을 나타내는 {{jsxref("Boolean")}}입니다. passive listener 가 preventDefault()를 호출하면 user agent는 콘솔 경고를 생성하는 것 외의 작업은 수행하지 않습니다. 자세한 내용은 {{anch("Improving scrolling performance with passive listeners")}} 를 참조하세요.
  • +
  • {{non-standard_inline}} mozSystemGroup: listener를 시스템 그룹에 추가해야함을 나타내는 {{jsxref("Boolean")}} 입니다. 오직 XBL 혹은 파이어폭스 브라우저의 {{glossary("chrome")}}에서 실행되는 코드에서만 사용할 수 있습니다.
  • +
+
+
useCapture {{optional_inline}}
+
DOM 트리의 하단에 있는 EventTarget 으로 전송하기 전에, 등록된 listener 로 이 타입의 이벤트의 전송여부를 나타내는 {{jsxref("Boolean")}} 입니다. 트리에서 위쪽으로 버블링되는 이벤트는 캡처를 사용하도록, 지정된 listener를 트리거하지 않습니다. 이벤트 버블링과 캡쳐는 두 요소(엘리먼트)가 해당 이벤트에 대한 핸들(함수)를 등록한 경우, 다른 요소 내에 중첩된 요소에서 발생하는 이벤트를 전파하는 두 가지 방법 입니다. 이벤트 전파 모드는 요소가 이벤트를 수신하는 순서를 판별합니다. 자세한 설명은 DOM Level 3 Events 과 JavaScript Event order 를 참조하세요. 값을 지정하지 않으면, useCapture 의 기본값은 false 입니다.
+
+
참고: 이벤트 타겟에 연결된 이벤트 리스너의 경우, 이벤트는 캡쳐링과 버블링 단계가 아니라 타겟 단계에 있습니다. 타겟 단계의 이벤트는 useCapture 매개변수(파라미터)와 상관없이, 그들이 등록된 순서대로 요소의 모든 리스너를 트리거합니다.
+ +
참고: useCapture 가 항상 선택사항인 것은 아닙니다. 가장 광범위한 브라우저 호환성을 위해 포함시키는 것이 좋습니다.
+
+
wantsUntrusted {{Non-standard_inline}}
+
파이어폭스(겍코) 명세의 매개변수 입니다. true의 경우, 리스너는 웹 컨텐츠에 의해 dispatch되는 합성 이벤트를 수신합니다. (기본값은 {{glossary("chrome")}} 브라우저의 경우 false , 보통의 웹 페이지에서는 true입니다.) 이 매개 변수는 브라우저 자체 뿐만 아니라, 에드온에게도 유용합니다.
+
+ +

Usage notes

+ +

이벤트 리스너 콜백

+ +

이벤트 리스너는 콜백 함수로 지정할 수 있습니다. 또는 {{domxref("EventListener.handleEvent", "handleEvent()")}} 메서드가 콜백 함수 역할을 하는 {{domxref("EventListener")}}를 구현하는 객체로 지정할 수 있습니다.

+ +

콜백 함수 자체는 handleEvent() 메서드와 동일한 매개 변수와 반환값을 가집니다. 즉, 콜백은 단일 매개 변수를 허용합니다: 발생한 이벤트를 설명하는 {{domxref("Event")}}에 기반한 객체이며, 아무것도 반환하지 않습니다.

+ +

예를들어 {{event("fullscreenchange")}} 와 {{event("fullscreenerror")}}를 처리하는데 사용할 수 있는 이벤트 핸들러 콜백은 다음과 같습니다:

+ +
function eventHandler(event) {
+  if (event.type == 'fullscreenchange') {
+    /* handle a full screen toggle */
+  } else /* fullscreenerror */ {
+    /* handle a full screen toggle error */
+  }
+}
+ +

옵션 지원을 안전하게 감지

+ +

이전 버전의 DOM 명세에선, addEventListener()의 세 번째 매개 변수는 캡쳐의 사용여부를 나타내는 Boolean값 이었습니다. 시간이 지남에 따라 더 많은 옵션이 필요하다는 것이 분명 해졌습니다. 함수에 매개 변수를 추가하는 대신 (옵션값을 처리할 때 엄청나게 복잡한 작업), 세 번째 매개 변수는 다양한 속성을 포함 할 수 있는 객체로 변경되었습니다. 이 객체는 이벤트 리스너를 제거하는 프로세스를 구성하는 옵션값을 정의할 수 있습니다.

+ +

지난 버전의 브라우저(뿐만 아니라 너무 오래된 브라우저)에서는 여전히 세 번째 매개 변수가 Boolean 이라고 가정하고 시나리오를 지능적으로 처리할 코드를 작성해야 합니다. 관심있는 각 옵션에 대해 기능 감지를 사용하여 이 작업을 수행할 수 있습니다.

+ +

예를들어서, passive 옵션을 확인하려면 다음과 같이 하세요 :

+ +
var passiveSupported = false;
+
+try {
+  var options = {
+    get passive() { // This function will be called when the browser
+                    //     attempts to access the passive property.
+      passiveSupported = true;
+    }
+  };
+
+  window.addEventListener("test", options, options);
+  window.removeEventListener("test", options, options);
+} catch(err) {
+  passiveSupported = false;
+}
+ +

이렇게 하면 passive 속성(프로퍼티)에 대한 getter함수를 사용하여 options 객체가 만들어집니다; get을 호출 할 경우 gtter는 플래그 passiveSupportedtrue로 설정합니다. 즉, 브라우저가 options 객체의 passive 속성 값을 검사하면 passiveSupportedtrue로 설정됩니다; 그렇지 않으면 false가 유지됩니다. 그리고 addEventListener()를 호출하여 가짜 이벤트 핸들러를 설정합니다. 해당 옵션을 지정하여 브라우저가 객체를 세 번째 매개 변수로 인식하면 옵션을 확인합니다. 그런 다음 removeEventListener() 를 호출하여 스스로 정리합니다. (handleEvent()는 호출되지 않은 이벤트 리스너에서는 무시됩니다.) 

+ +

이 방법으로 지원되는 옵션이 있는지 확인할 수 있습니다. 위와 비슷한 코드를 사용하여 해당 옵션에 대한 getter를 추가하기 만하면됩니다.

+ +

그런 다음 문제의 옵션을 사용하는 실제 이벤트 리스너를 만들려면 다음과 같이 쓸 수 있습니다:

+ +
someElement.addEventListener("mouseup", handleMouseUp, passiveSupported
+                               ? { passive: true } : false);
+ +

여기에서는 {{event("mouseup")}} 이벤트에 대한 리스너를 someElement요소에 추가합니다.  새 번째 매개변수의 경우 passiveSupported가 true면, options 객체를 passive : true 로 설정합니다; 그렇지 않으면, 우리는 Boolean을 전달해야 함올 알고있습니다. useCapture 매개변수의 값으로 false 를 전달합니다.

+ +

원하는 경우 Modernizr 혹은 Detect It 과 같은 서드파티 라이브러리를 사용하여 이러한 테스트를 수행할 수 있습니다.

+ +

Web Incubator Community Group의 EventListenerOptions에 대한 기사에서 더 많은 것을 배울 수 있습니다.

+ +

예제

+ +

간단한 리스너 추가

+ +

이 예제는 addEventListener() 를 사용하여 요소에 대한 마우스 클릭을 감지하는 방법을 보여줍니다.

+ +

HTML

+ +
<table id="outside">
+    <tr><td id="t1">one</td></tr>
+    <tr><td id="t2">two</td></tr>
+</table>
+
+ +

JavaScript

+ +
// Function to change the content of t2
+function modifyText() {
+  var t2 = document.getElementById("t2");
+  if (t2.firstChild.nodeValue == "three") {
+    t2.firstChild.nodeValue = "two";
+  } else {
+    t2.firstChild.nodeValue = "three";
+  }
+}
+
+// add event listener to table
+var el = document.getElementById("outside");
+el.addEventListener("click", modifyText, false);
+
+ +

이 코드에서, modifyText() 는 addEventListener()를 사용하여 등록된 click 이벤트에 대한 리스너입니다. 테이블의 아무곳이나 클릭하더라도, 핸들러에서 버블링되고 modifyText() 가 실행됩니다.

+ +

결과

+ +

{{EmbedLiveSample('간단한_리스너_추가')}}

+ +

익명 함수와 이벤트 리스너

+ +

여기서는 익명 함수를 사용하여 매개 변수를 이벤트 리스너에 전달하는 방법을 살펴보겠습니다.

+ +

HTML

+ +
<table id="outside">
+    <tr><td id="t1">one</td></tr>
+    <tr><td id="t2">two</td></tr>
+</table>
+ +

JavaScript

+ +
// Function to change the content of t2
+function modifyText(new_text) {
+  var t2 = document.getElementById("t2");
+  t2.firstChild.nodeValue = new_text;
+}
+
+// Function to add event listener to table
+var el = document.getElementById("outside");
+el.addEventListener("click", function(){modifyText("four")}, false);
+
+ +

리스너는 코드를 캡슐화 하는 익명 함수입니다. 이 익명의 함수는 실제로 이벤트에 응답하는 책임이 있는 modifyText() 함수에 매개변수를 전달 할 수 있습니다.

+ +

Result

+ +

{{EmbedLiveSample('익명_함수와_이벤트_리스너')}}

+ +

화살표 함수와 이벤트 리스너

+ +

이 예제는 화살표 함수를 사용하여 구현된 간단한 이벤트 리스너를 보여줍니다. 

+ +

HTML

+ +
<table id="outside">
+    <tr><td id="t1">one</td></tr>
+    <tr><td id="t2">two</td></tr>
+</table>
+ +

JavaScript

+ +
// Function to change the content of t2
+function modifyText(new_text) {
+  var t2 = document.getElementById("t2");
+  t2.firstChild.nodeValue = new_text;
+}
+
+// Add event listener to table with an arrow function
+var el = document.getElementById("outside");
+el.addEventListener("click", () => { modifyText("four"); }, false);
+
+ +

결과

+ +

{{EmbedLiveSample('화살표_함수와_이벤트_리스너')}}

+ +

화살표 함수와 익명 함수는 유사하지만 서로 다른 this바인딩을 가집니다. 익명(모든 전통적인 자바스크립트 함수)는 그들 자신의 this 바인딩을 만들지만, 화살표 함수는 포함하고 있는 함수의 this바인딩을 상속합니다.

+ +

즉, 화살표 함수를 사용할 때 포함하고 있는 함수에서 사용중인 변수 및 상수를 이벤트 핸들러에서 사용할 수 있습니다.

+ +

옵션의 사용 예제

+ +

HTML

+ +
<div class="outer">
+    outer, once & none-once
+    <div class="middle" target="_blank">
+        middle, capture & none-capture
+        <a class="inner1" href="https://www.mozilla.org" target="_blank">
+            inner1, passive & preventDefault(which is not allowed)
+        </a>
+        <a class="inner2" href="https://developer.mozilla.org/" target="_blank">
+            inner2, none-passive & preventDefault(not open new page)
+        </a>
+    </div>
+</div>
+
+ +

CSS

+ +
    .outer, .middle, .inner1, .inner2 {
+        display:block;
+        width:520px;
+        padding:15px;
+        margin:15px;
+        text-decoration:none;
+    }
+    .outer{
+        border:1px solid red;
+        color:red;
+    }
+    .middle{
+        border:1px solid green;
+        color:green;
+        width:460px;
+    }
+    .inner1, .inner2{
+        border:1px solid purple;
+        color:purple;
+        width:400px;
+    }
+
+ +

JavaScript

+ +
    let outer  = document.getElementsByClassName('outer') [0];
+    let middle = document.getElementsByClassName('middle')[0];
+    let inner1 = document.getElementsByClassName('inner1')[0];
+    let inner2 = document.getElementsByClassName('inner2')[0];
+
+    let capture = {
+        capture : true
+    };
+    let noneCapture = {
+        capture : false
+    };
+    let once = {
+        once : true
+    };
+    let noneOnce = {
+        once : false
+    };
+    let passive = {
+        passive : true
+    };
+    let nonePassive = {
+        passive : false
+    };
+
+
+    outer.addEventListener('click', onceHandler, once);
+    outer.addEventListener('click', noneOnceHandler, noneOnce);
+    middle.addEventListener('click', captureHandler, capture);
+    middle.addEventListener('click', noneCaptureHandler, noneCapture);
+    inner1.addEventListener('click', passiveHandler, passive);
+    inner2.addEventListener('click', nonePassiveHandler, nonePassive);
+
+    function onceHandler(event)
+    {
+        alert('outer, once');
+    }
+    function noneOnceHandler(event)
+    {
+        alert('outer, none-once, default');
+    }
+    function captureHandler(event)
+    {
+        //event.stopImmediatePropagation();
+        alert('middle, capture');
+    }
+    function noneCaptureHandler(event)
+    {
+        alert('middle, none-capture, default');
+    }
+    function passiveHandler(event)
+    {
+        // Unable to preventDefault inside passive event listener invocation.
+        event.preventDefault();
+        alert('inner1, passive, open new page');
+    }
+    function nonePassiveHandler(event)
+    {
+        event.preventDefault();
+        //event.stopPropagation();
+        alert('inner2, none-passive, default, not open new page');
+    }
+
+ +

Result

+ +

옵션이 어떻게 작동하는지 보려면 각각 outer, middle, inner 컨테이너를 클릭해 보세요.

+ +

{{ EmbedLiveSample('옵션의_사용_예제', 600, 310, '', 'Web/API/EventTarget/addEventListener') }}

+ +

options 객체에서 특정 값을 사용하기 전에, 모든 브라우저의 모든 버전이 지원하는 것은 아니므로, 사용자의 브라우저가 해당 기능을 지원하는지 확인하는 것이 좋습니다. 자세한 내용은 {{anch("Safely detecting option support")}} 을 참조하세요.

+ +

Other notes

+ +

addEventListener를 사용하나요?

+ +

addEventListener() 는 W3C 에서 지정한 DOM에 이벤트 리스너를 등록하는 방법입니다. 장점은 다음과 같습니다:

+ + + +

대안으로, 이벤트 리스너를 등록하는 오래된 방법은 아래에 설명되어 있습니다.

+ +

이벤트 전달중에 리스너 추가

+ +

{{domxref("EventListener")}} 가 이벤트 처리중에 {{domxref("EventTarget")}}에 추가되었다면, 그 이벤트는 리스너를 트리거하지 않습니다. 그러나 동일한 리스너는 버블링 단계와 같은 이벤트 흐름의 나중 단계에서 트리거 될 수 있습니다. 

+ +

다수의 동일한 이벤트 리스너

+ +

만약 동일한 여러개의 EventListener 가 동일한 매개변수(parameter)로 동일한 EventTarget 에 등록되었다면, 중복된 항목(인스턴스)들은 버려집니다. EventListener는 두번 호출되지 않으며 {{domxref("EventTarget.removeEventListener", "removeEventListener()")}} 메서드를 사용해 직접 제거할 필요가 없습니다. 그러나 익명 함수를 핸들러로 사용할 때, 루프를 도는 경우가 있습니다. 이 경우 단순히 반복적으로 호출하는 동일한 소스 코드를 사용하여 이벤트를 등록하더라도, 익명 함수는 동일하지 않고 이 때문에 리스너 또한 동일하지 않습니다. 이와 같은 경우 동일한 함수를 반복적으로 정의하는 것이 더 문제가 될 수 있습니다. (아래의 메모리 문제를 참조하세요.)

+ +

핸들러 내부의 this 값

+ +

유사한 요소 집합에 대한 일반적인 핸들러를 사용할 때와 같이, 이벤트 핸들러가 동작한 엘리먼트를 참조하는것이 좋습니다.

+ +

addEventListener() 를 사용하여 핸들러 함수를 요소에 연결하면, 핸들러 내부의 this 값은 요소에 대한 참조입니다. 이것은 핸들러에 전달 된 이벤트 인수(아규먼트)의 currentTarget 속성(프로퍼티)값과 같습니다.

+ +
my_element.addEventListener('click', function (e) {
+  console.log(this.className)           // logs the className of my_element
+  console.log(e.currentTarget === this) // logs `true`
+})
+
+ +

다시 말해, 화살표 함수에는 this 컨텍스트가 없습니다.

+ +
my_element.addEventListener('click', (e) => {
+  console.log(this.className)           // WARNING: `this` is not `my_element`
+  console.log(e.currentTarget === this) // logs `false`
+})
+ +

HTML 소스의 요소(element)에 이벤트 핸들러(예: onclick)가 지정된 경우, 속성 값(attribute value)의 자바스크립트 코드는 효과적으로 addEventListener() 에 따라  this값을 바인드하는 핸들러 함수로 래핑됩니다. 코드 내에서 this가 발생하면 요소에 대한 참조를 나타냅니다.

+ +
<table id="my_table" onclick="console.log(this.id);"><!-- `this` refers to the table; logs 'my_table' -->
+  ...
+</table>
+
+ +

속성 값(attribute value)의 코드에 의해 호출 된 함수 내부의 this 는 표준 규칙들에 따라 동작합니다. 다음은 그 예입니다.

+ +
<script>
+  function logID() { console.log(this.id); }
+</script>
+<table id="my_table" onclick="logID();"><!-- when called, `this` will refer to the global object -->
+  ...
+</table>
+
+
+ +

logID() 내의 this 값은 {{domxref("Window")}} 전역 객체에 대한 참조입니다. (혹은 strict mode 의 경우 undefined입니다.)

+ +

bind()를 사용하여 this지정하기

+ +

Function.prototype.bind() 메서드를 사용하면 지정한 함수에 대한 모든 호출에 대해 this 값으로 사용해야 하는 값을 지정할 수 있습니다. 이를 이용하여 함수가 호출 된 컨텍스트에 따라 this 가 무엇인지 명확하지 않은 문제를 쉽게 우회할 수 있습니다. 그러나 나중에 제거할 수 있도록, 주위에 리스너에 대한 참조를 유지해야 합니다.

+ +

다음은 bind() 를 사용한, 사용하지 않은 예제입니다 :

+ +
var Something = function(element) {
+  // |this| is a newly created object
+  this.name = 'Something Good';
+  this.onclick1 = function(event) {
+    console.log(this.name); // undefined, as |this| is the element
+  };
+  this.onclick2 = function(event) {
+    console.log(this.name); // 'Something Good', as |this| is bound to newly created object
+  };
+  element.addEventListener('click', this.onclick1, false);
+  element.addEventListener('click', this.onclick2.bind(this), false); // Trick
+}
+var s = new Something(document.body);
+
+ +

또 다른 해결책은 handleEvent()라는 특수 함수를 사용하여 어떤 이벤트를 캐치 하는것입니다 :

+ +
var Something = function(element) {
+  // |this| is a newly created object
+  this.name = 'Something Good';
+  this.handleEvent = function(event) {
+    console.log(this.name); // 'Something Good', as this is bound to newly created object
+    switch(event.type) {
+      case 'click':
+        // some code here...
+        break;
+      case 'dblclick':
+        // some code here...
+        break;
+    }
+  };
+
+  // Note that the listeners in this case are |this|, not this.handleEvent
+  element.addEventListener('click', this, false);
+  element.addEventListener('dblclick', this, false);
+
+  // You can properly remove the listeners
+  element.removeEventListener('click', this, false);
+  element.removeEventListener('dblclick', this, false);
+}
+var s = new Something(document.body);
+
+ +

this에 대한 참조를 처리하는 또 다른 방법은, EventListener 에 함수를 전달하는 것입니다. 이 함수는 접근을 필요로 하는 필드가 들어있는, 객체의 메서드를 호출하는 함수입니다:

+ +
class SomeClass {
+
+  constructor() {
+    this.name = 'Something Good';
+  }
+
+  register() {
+    var that = this;
+    window.addEventListener('keydown', function(e) {return that.someMethod(e);});
+  }
+
+  someMethod(e) {
+    console.log(this.name);
+    switch(e.keyCode) {
+      case 5:
+        // some code here...
+        break;
+      case 6:
+        // some code here...
+        break;
+    }
+  }
+
+}
+
+var myObject = new SomeClass();
+myObject.register();
+ +

오래된 인터넷 익스플로러와 attachEvent

+ +

인터넷 익스플로러 9 이전 버전에서는, 표준 addEventListener() 가 아닌 {{domxref("EventTarget.attachEvent", "attachEvent()")}}를 사용해야 합니다. IE의 경우 위의 예제를 다음과 같이 수정합니다:

+ +
if (el.addEventListener) {
+  el.addEventListener('click', modifyText, false);
+} else if (el.attachEvent)  {
+  el.attachEvent('onclick', modifyText);
+}
+
+ +

attachEvent()의 단점은 다음과 같습니다: this의 값이 이벤트가 바인드되어 있는 요소 대신에, window객체에 대한 참조가 됩니다.

+ +

attachEvent() 메서드는 onresize 이벤트와 쌍을 이루어 웹 페이지의 특정 요소의 크기가 리사이징 되는 시점을 감지할 수 있습니다. mselementresize 라는 독점적인 이벤트는, 이벤트 핸들러를 등록하는 addEventListener 메서드와 함께 사용할 때 onresize와 유사한 기능을 제공하여, 특정 HTML 요소의 크기를 리사이징 할 때 실행됩니다.

+ +

호환성

+ +

스크립트 시작 부분에 다음 코드를 사용하여, 인터넷 익스플로러 8 에서 지원하지 않는 addEventListener(), removeEventListener(), {{domxref("Event.preventDefault()")}}, {{domxref("Event.stopPropagation()")}} 을 해결할 수 있습니다. 이 코드는 handleEvent()와 {{event("DOMContentLoaded")}} 이벤트에 대한 사용을 지원합니다.

+ +
+

참고: IE8 에서는 useCapture를 지원할 수 있는 다른 방법이 없습니다. 다음의 코드는 IE8 지원만 추가합니다. 이 IE8 폴리필은 표준 모드에서만 작동합니다: doctype 선언이 필요합니다.

+
+ +
(function() {
+  if (!Event.prototype.preventDefault) {
+    Event.prototype.preventDefault=function() {
+      this.returnValue=false;
+    };
+  }
+  if (!Event.prototype.stopPropagation) {
+    Event.prototype.stopPropagation=function() {
+      this.cancelBubble=true;
+    };
+  }
+  if (!Element.prototype.addEventListener) {
+    var eventListeners=[];
+
+    var addEventListener=function(type,listener /*, useCapture (will be ignored) */) {
+      var self=this;
+      var wrapper=function(e) {
+        e.target=e.srcElement;
+        e.currentTarget=self;
+        if (typeof listener.handleEvent != 'undefined') {
+          listener.handleEvent(e);
+        } else {
+          listener.call(self,e);
+        }
+      };
+      if (type=="DOMContentLoaded") {
+        var wrapper2=function(e) {
+          if (document.readyState=="complete") {
+            wrapper(e);
+          }
+        };
+        document.attachEvent("onreadystatechange",wrapper2);
+        eventListeners.push({object:this,type:type,listener:listener,wrapper:wrapper2});
+
+        if (document.readyState=="complete") {
+          var e=new Event();
+          e.srcElement=window;
+          wrapper2(e);
+        }
+      } else {
+        this.attachEvent("on"+type,wrapper);
+        eventListeners.push({object:this,type:type,listener:listener,wrapper:wrapper});
+      }
+    };
+    var removeEventListener=function(type,listener /*, useCapture (will be ignored) */) {
+      var counter=0;
+      while (counter<eventListeners.length) {
+        var eventListener=eventListeners[counter];
+        if (eventListener.object==this && eventListener.type==type && eventListener.listener==listener) {
+          if (type=="DOMContentLoaded") {
+            this.detachEvent("onreadystatechange",eventListener.wrapper);
+          } else {
+            this.detachEvent("on"+type,eventListener.wrapper);
+          }
+          eventListeners.splice(counter, 1);
+          break;
+        }
+        ++counter;
+      }
+    };
+    Element.prototype.addEventListener=addEventListener;
+    Element.prototype.removeEventListener=removeEventListener;
+    if (HTMLDocument) {
+      HTMLDocument.prototype.addEventListener=addEventListener;
+      HTMLDocument.prototype.removeEventListener=removeEventListener;
+    }
+    if (Window) {
+      Window.prototype.addEventListener=addEventListener;
+      Window.prototype.removeEventListener=removeEventListener;
+    }
+  }
+})();
+ +

이벤트 리스너를 등록하는 고전적인 방법

+ +

addEventListener()는 DOM 2 Events 명세와 함께 도입되었습니다. 그 전에는 다음과 같이 이벤트 리스너를 등록했습니다:

+ +
// Passing a function reference ? do not add '()' after it, which would call the function!
+el.onclick = modifyText;
+
+// Using a function expression
+element.onclick = function() {
+  // ... function logic ...
+};
+
+ +

This 이 메서드는 요소의 기존 click 이벤트 리스너가 있을 경우에, 그것을 대체합니다. blur (onblur) 및 keypress (onkeypress) 와 같은 다른 이벤트 및 이벤트 핸들러도 비슷하게 작동합니다.

+ +

이것은 본질적으로 {{glossary("DOM", "DOM 0")}}의 일부였기 때문에, 이벤트 리스너를 추가하는데 매우 광범위하게 지원되며 특별한 크로스 브라우징 코드가 필요하지 않습니다. 이것은 일반적으로 addEventListener()의 추가 기능이 필요하지 않으면, 이벤트 리스너를 동적으로 등록하는데 사용합니다.

+ +

메모리 이슈

+ +
var i;
+var els = document.getElementsByTagName('*');
+
+// Case 1
+for(i=0 ; i<els.length ; i++){
+  els[i].addEventListener("click", function(e){/*do something*/}, false);
+}
+
+// Case 2
+function processEvent(e){
+  /*do something*/
+}
+
+for(i=0 ; i<els.length ; i++){
+  els[i].addEventListener("click", processEvent, false);
+}
+
+ +

위의 첫 번째 경우, 루프의 각 반복마다 새로운 익명 핸들러 함수가 생성됩니다. 두 번째 경우에는 이전에 선언한 동일한 함수를 이벤트 핸들러로 사용하므로, 메모리 소비가 줄어듭니다. 또한 첫 번째 경우에는 removeEventListener()를 호출할 수 없습니다. 익명 함수에 대한 참조가 유지되지 않기 때문입니다.(루프가 생성할 수 있는 여러개의 익명 함수 중 하나에 보관되지 않습니다) 두 번째 경우에는 processEvent가 함수 참조이기 때문에, myElement.removeEventListener("click", processEvent, false)를 수행할 수 있습니다.

+ +

사실, 메모리 소비와 관련하여, 함수 참조를 유지하는 것은 진짜 문제가 아닙니다. 오히려 정적 함수 참조를 유지하는 것이 부족합니다. 아래의 두 경우(3,4번째 케이스) 모두 함수 참조가 유지되지만, 각 반복에서 재정의 되므로 정적이 아닙니다. 세 번째 경우에는 익명 함수에 대한 참조가, 반복될 때 마다 다시 할당됩니다. 네 번째 경우에는 전체 함수 정의가 변경되지 않지만, 새로운 것처럼(컴파일러에 의해 [[promoted]]되지 않는 한) 반복적으로 정의되고 있고 그래서 정적이지 않습니다. 따라서 간단하게 [[여러개의 동일한 이벤트 리스너]]인 것처럼 보이지만, 두 경우 모두 각 반복은 핸들러 함수에 대한 고유한 참조로 새로운 리스너를 생성합니다. 그러나 함수 정의 자체는 변경되지 않으므로, 모든 중복 리스너에 대해 같은 함수가 여전히 호출될 수 있습니다.(특히 코드가 최적화되는 경우)

+ +

또한 두 경우 모두 함수 참조가 유지되었지만, 각 가산에 대해 반복적으로 재정의 되었습니다. 위에서 사용했던 remove 문(statement)으로는 리스너를 제거할 수 있지만, 마지막으로 추가한 리스너만 제거됩니다.

+ +
// For illustration only: Note "MISTAKE" of [j] for [i] thus causing desired events to all attach to SAME element
+
+// Case 3
+for(var i=0, j=0 ; i<els.length ; i++){
+  /*do lots of stuff with j*/
+  els[j].addEventListener("click", processEvent = function(e){/*do something*/}, false);
+}
+
+// Case 4
+for(var i=0, j=0 ; i<els.length ; i++){
+  /*do lots of stuff with j*/
+  function processEvent(e){/*do something*/};
+  els[j].addEventListener("click", processEvent, false);
+}
+ +

passive 리스너로 스크롤링 성능 향상

+ +

명세에 따르면, passive option의 기본값은 항상 false 입니다. 그러나 이것은 이벤트 리스너가 특정 터치 이벤트를 처리하는 경우(다른 이벤트를 포함하여), 스크롤을 처리하는 동안 브라우저의 메인 스레드를 차단하기 때문에, 스크롤 처리 시 성능이 크게 저하될 수 있습니다.

+ +

이러한 문제를 방지하기 위하여, 일부 브라우저(특히 크롬과 파이어폭스)는 document-level nodes인 {{domxref("Window")}}, {{domxref("Document")}}, {{domxref("Document.body")}}의 경우 {{event("touchstart")}} 와{{event("touchmove")}} 이벤트에 대해 passive 옵션의 기본값을 true로 변경했습니다. 이렇게 하면 이벤트 리스너가 호출되지 않으므로, 사용자가 스크롤 하는 동안 페이지 렌더링을 차단할 수 없습니다.

+ +
+

참고: 이 변경된 동작을 구현하는 브라우저(혹은 브라우저의 버전)을 알아야 할 경우 아래의 호환성 표를 참조하세요.

+
+ +

다음과 같이 passive의 값을 명시적으로 false로 설정을 오버라이드 하여 이 동작을 무시할 수 있습니다:

+ +
/* Feature detection */
+var passiveIfSupported = false;
+
+try {
+  window.addEventListener("test", null, Object.defineProperty({}, "passive", { get: function() { passiveIfSupported = { passive: true }; } }));
+} catch(err) {}
+
+window.addEventListener('scroll', function(event) {
+  /* do something */
+  // can't use event.preventDefault();
+}, passiveIfSupported );
+
+ +

addEventListener()에 대한 options 매개변수를 지원하지 않는 이전 브라우저에서는, feature detection를 사용하지 않고는 useCapture 인수를 사용하지 못하도록 해야 합니다.

+ +

{{event("scroll")}} 이벤트의 기본 passive 값에 대해 걱정할 필요는 없습니다. 취소할 수 없기 때문에, 이벤트 리스너는 페이지 렌더링을 차단할 수 없습니다.

+ +

명세

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName("DOM WHATWG", "#dom-eventtarget-addeventlistener", "EventTarget.addEventListener()")}}{{Spec2("DOM WHATWG")}} 
{{SpecName("DOM4", "#dom-eventtarget-addeventlistener", "EventTarget.addEventListener()")}}{{Spec2("DOM4")}} 
{{SpecName("DOM2 Events", "#Events-EventTarget-addEventListener", "EventTarget.addEventListener()")}}{{Spec2("DOM2 Events")}}Initial definition
+ +

브라우저 호환성

+ + + +

{{Compat("api.EventTarget.addEventListener", 3)}}

+ +

같이 보기

+ + diff --git a/files/ko/web/api/eventtarget/dispatchevent/index.html b/files/ko/web/api/eventtarget/dispatchevent/index.html deleted file mode 100644 index 528b506c57..0000000000 --- a/files/ko/web/api/eventtarget/dispatchevent/index.html +++ /dev/null @@ -1,75 +0,0 @@ ---- -title: EventTarget.dispatchEvent() -slug: Web/API/EventTarget/dispatchEvent -tags: - - API - - DOM - - DOM 엘리먼트 메소드 - - Gecko - - 메소드 -translation_of: Web/API/EventTarget/dispatchEvent ---- -

{{APIRef("DOM Events")}}

- -

영향을 받는 {{domxref("EventListener")}} 를 적절한 순서로 호출하는 지정된 {{domxref("EventTarget")}} 에서 {{domxref("Event")}} 를 (동기적으로) 디스패치합니다. 일반 이벤트 처리 규칙(capturing 과 선택적인 bubbling 단계를 포함해)은 dispatchEvent() 를 사용하여 수동으로 전달 된 이벤트에도 적용됩니다.

- -

구문

- -
cancelled = !target.dispatchEvent(event)
-
- -

파라미터

- - - -

반환 값

- - - -

dispatchEvent 메서드는 그 이벤트의 타입이 메서드의 호출이전에 초기화되지 않았을 경우 UNSPECIFIED_EVENT_TYPE_ERR 에러를 발생시킵니다. 또는 이벤트의 타입이 null 이거나 공백 스트링을 경우에도 같은 에러를 발생시킵니다. 이벤트 핸들러에 의해 발생한 이벤트는 잡히지 않은 예외(uncaugt exceptions)로 보고가 되며 이벤트 핸들러는 내부 콜스택(nested callstack)에서 실행이 됩니다. 이는 곧 완료가 될 때까지 호출자(caller)를 막는 다는 뜻이고 예외들이 호출자(caller)에게 전파(propagate)되지 않음을 말합니다. 

- -

노트

- -

DOM에 의해 시작되고 이벤트 루프를 통해 이벤트 핸들러를 비동기 적으로 호출하는 "네이티브" 이벤트와 달리 dispatchEvent 는 이벤트 핸들러를 동기적으로 호출합니다. dispatchEvent 를 호출 한 후 코드가 계속되기 전에 모든 해당 이벤트 핸들러가 실행되고 리턴됩니다.

- -

implementation's 이벤트 모델의 디스패치 이벤트에 사용되는 create-init-dispatch 프로세스의 마지막 단계입니다. 이벤트는 Event 생성자를 사용하여 만들 수 있습니다.

- -

Event 객체 레퍼런스도 한번 확인해 보세요

- -

예시

- -

이벤트 생성 및 트리거 문서를 확인하세요.

- -

명세

- - - - - - - - - - - - - - - - -
명세상태코멘트
{{SpecName('DOM WHATWG', '#dom-eventtarget-dispatchevent', 'EventTarget.dispatchEvent()')}}{{ Spec2('DOM WHATWG') }}DOM 2 Events 명세의 초기 정의.
- -

브라우저 호환성

- -

 

- -

 

- -

{{Compat("api.EventTarget.dispatchEvent")}}

- -

 

diff --git a/files/ko/web/api/eventtarget/dispatchevent/index.md b/files/ko/web/api/eventtarget/dispatchevent/index.md new file mode 100644 index 0000000000..528b506c57 --- /dev/null +++ b/files/ko/web/api/eventtarget/dispatchevent/index.md @@ -0,0 +1,75 @@ +--- +title: EventTarget.dispatchEvent() +slug: Web/API/EventTarget/dispatchEvent +tags: + - API + - DOM + - DOM 엘리먼트 메소드 + - Gecko + - 메소드 +translation_of: Web/API/EventTarget/dispatchEvent +--- +

{{APIRef("DOM Events")}}

+ +

영향을 받는 {{domxref("EventListener")}} 를 적절한 순서로 호출하는 지정된 {{domxref("EventTarget")}} 에서 {{domxref("Event")}} 를 (동기적으로) 디스패치합니다. 일반 이벤트 처리 규칙(capturing 과 선택적인 bubbling 단계를 포함해)은 dispatchEvent() 를 사용하여 수동으로 전달 된 이벤트에도 적용됩니다.

+ +

구문

+ +
cancelled = !target.dispatchEvent(event)
+
+ +

파라미터

+ + + +

반환 값

+ + + +

dispatchEvent 메서드는 그 이벤트의 타입이 메서드의 호출이전에 초기화되지 않았을 경우 UNSPECIFIED_EVENT_TYPE_ERR 에러를 발생시킵니다. 또는 이벤트의 타입이 null 이거나 공백 스트링을 경우에도 같은 에러를 발생시킵니다. 이벤트 핸들러에 의해 발생한 이벤트는 잡히지 않은 예외(uncaugt exceptions)로 보고가 되며 이벤트 핸들러는 내부 콜스택(nested callstack)에서 실행이 됩니다. 이는 곧 완료가 될 때까지 호출자(caller)를 막는 다는 뜻이고 예외들이 호출자(caller)에게 전파(propagate)되지 않음을 말합니다. 

+ +

노트

+ +

DOM에 의해 시작되고 이벤트 루프를 통해 이벤트 핸들러를 비동기 적으로 호출하는 "네이티브" 이벤트와 달리 dispatchEvent 는 이벤트 핸들러를 동기적으로 호출합니다. dispatchEvent 를 호출 한 후 코드가 계속되기 전에 모든 해당 이벤트 핸들러가 실행되고 리턴됩니다.

+ +

implementation's 이벤트 모델의 디스패치 이벤트에 사용되는 create-init-dispatch 프로세스의 마지막 단계입니다. 이벤트는 Event 생성자를 사용하여 만들 수 있습니다.

+ +

Event 객체 레퍼런스도 한번 확인해 보세요

+ +

예시

+ +

이벤트 생성 및 트리거 문서를 확인하세요.

+ +

명세

+ + + + + + + + + + + + + + + + +
명세상태코멘트
{{SpecName('DOM WHATWG', '#dom-eventtarget-dispatchevent', 'EventTarget.dispatchEvent()')}}{{ Spec2('DOM WHATWG') }}DOM 2 Events 명세의 초기 정의.
+ +

브라우저 호환성

+ +

 

+ +

 

+ +

{{Compat("api.EventTarget.dispatchEvent")}}

+ +

 

diff --git a/files/ko/web/api/eventtarget/eventtarget/index.html b/files/ko/web/api/eventtarget/eventtarget/index.html deleted file mode 100644 index 054c831826..0000000000 --- a/files/ko/web/api/eventtarget/eventtarget/index.html +++ /dev/null @@ -1,70 +0,0 @@ ---- -title: EventTarget() -slug: Web/API/EventTarget/EventTarget -translation_of: Web/API/EventTarget/EventTarget ---- -
{{APIRef("DOM Events")}}
- -

EventTarget() 생성자는 새로운 {{domxref("EventTarget")}} 객체 인스턴스를 만듭니다.

- -

Syntax

- -
var myEventTarget = new EventTarget();
- -

Parameters

- -

None.

- -

Return value

- -

{{domxref("EventTarget")}} 객체의 인스턴스를 반환합니다.

- -

Examples

- -
class MyEventTarget extends EventTarget {
-  constructor(mySecret) {
-    super();
-    this._secret = mySecret;
-  }
-
-  get secret() { return this._secret; }
-};
-
-let myEventTarget = new MyEventTarget(5);
-let value = myEventTarget.secret;  // == 5
-myEventTarget.addEventListener("foo", function(e) {
-  this._secret = e.detail;
-});
-
-let event = new CustomEvent("foo", { detail: 7 });
-myEventTarget.dispatchEvent(event);
-let newValue = myEventTarget.secret; // == 7
- -

Specifications

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('DOM WHATWG', '#dom-eventtarget-eventtarget', 'EventTarget() constructor')}}{{Spec2('DOM WHATWG')}} 
- -

Browser compatibility

- - - -

{{Compat("api.EventTarget.EventTarget")}}

- -

See also

- - diff --git a/files/ko/web/api/eventtarget/eventtarget/index.md b/files/ko/web/api/eventtarget/eventtarget/index.md new file mode 100644 index 0000000000..054c831826 --- /dev/null +++ b/files/ko/web/api/eventtarget/eventtarget/index.md @@ -0,0 +1,70 @@ +--- +title: EventTarget() +slug: Web/API/EventTarget/EventTarget +translation_of: Web/API/EventTarget/EventTarget +--- +
{{APIRef("DOM Events")}}
+ +

EventTarget() 생성자는 새로운 {{domxref("EventTarget")}} 객체 인스턴스를 만듭니다.

+ +

Syntax

+ +
var myEventTarget = new EventTarget();
+ +

Parameters

+ +

None.

+ +

Return value

+ +

{{domxref("EventTarget")}} 객체의 인스턴스를 반환합니다.

+ +

Examples

+ +
class MyEventTarget extends EventTarget {
+  constructor(mySecret) {
+    super();
+    this._secret = mySecret;
+  }
+
+  get secret() { return this._secret; }
+};
+
+let myEventTarget = new MyEventTarget(5);
+let value = myEventTarget.secret;  // == 5
+myEventTarget.addEventListener("foo", function(e) {
+  this._secret = e.detail;
+});
+
+let event = new CustomEvent("foo", { detail: 7 });
+myEventTarget.dispatchEvent(event);
+let newValue = myEventTarget.secret; // == 7
+ +

Specifications

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('DOM WHATWG', '#dom-eventtarget-eventtarget', 'EventTarget() constructor')}}{{Spec2('DOM WHATWG')}} 
+ +

Browser compatibility

+ + + +

{{Compat("api.EventTarget.EventTarget")}}

+ +

See also

+ + diff --git a/files/ko/web/api/eventtarget/index.html b/files/ko/web/api/eventtarget/index.html deleted file mode 100644 index 5addf5b9d6..0000000000 --- a/files/ko/web/api/eventtarget/index.html +++ /dev/null @@ -1,133 +0,0 @@ ---- -title: EventTarget -slug: Web/API/EventTarget -tags: - - API - - DOM - - DOM Events - - EventTarget - - Interface - - Reference -translation_of: Web/API/EventTarget ---- -
{{ApiRef("DOM Events")}}
- -

EventTarget은 이벤트를 받을 수 있으며, 이벤트에 대한 수신기(listener)를 가질 수 있는 객체가 구현하는 DOM 인터페이스입니다.

- -

{{domxref("Element")}}, {{domxref("document")}} 및 {{domxref("window")}}가 가장 흔한 이벤트 대상이지만, 다른 객체, 예컨대 {{domxref("XMLHttpRequest")}}, {{domxref("AudioNode")}}, {{domxref("AudioContext")}} 등 역시 이벤트 대상이 될 수 있습니다.

- -

많은 이벤트 대상(요소, 문서, 창, ...)은 onevent 속성과 특성을 사용한 이벤트 처리기 등록도 지원합니다.

- -

{{InheritanceDiagram}}

- -

생성자

- -
-
{{domxref("EventTarget.EventTarget()", "EventTarget()")}}
-
새로운 EventTarget 객체 인스턴스를 생성합니다.
-
- -

메서드

- -
-
{{domxref("EventTarget.addEventListener()")}}
-
EventTarget에 특정 이벤트 유형의 이벤트 처리기를 등록합니다.
-
{{domxref("EventTarget.removeEventListener()")}}
-
EventTarget에서 주어진 이벤트 수신기를 제거합니다.
-
{{domxref("EventTarget.dispatchEvent()")}}
-
EventTarget에 이벤트를 디스패치 합니다.
-
- - - -

예제

- -

간단한 EventTarget 구현

- -
var EventTarget = function() {
-  this.listeners = {};
-};
-
-EventTarget.prototype.listeners = null;
-EventTarget.prototype.addEventListener = function(type, callback) {
-  if (!(type in this.listeners)) {
-    this.listeners[type] = [];
-  }
-  this.listeners[type].push(callback);
-};
-
-EventTarget.prototype.removeEventListener = function(type, callback) {
-  if (!(type in this.listeners)) {
-    return;
-  }
-  var stack = this.listeners[type];
-  for (var i = 0, l = stack.length; i < l; i++) {
-    if (stack[i] === callback){
-      stack.splice(i, 1);
-      return;
-    }
-  }
-};
-
-EventTarget.prototype.dispatchEvent = function(event) {
-  if (!(event.type in this.listeners)) {
-    return true;
-  }
-  var stack = this.listeners[event.type].slice();
-
-  for (var i = 0, l = stack.length; i < l; i++) {
-    stack[i].call(this, event);
-  }
-  return !event.defaultPrevented;
-};
-
- -

명세

- - - - - - - - - - - - - - - - - - - - - - - - -
명세상태설명
{{SpecName('DOM WHATWG', '#interface-eventtarget', 'EventTarget')}}{{Spec2('DOM WHATWG')}}변화 없음.
{{SpecName('DOM3 Events', 'DOM3-Events.html#interface-EventTarget', 'EventTarget')}}{{Spec2('DOM3 Events')}}매개변수 약간이 이제 선택사항(listener) 또는 null 값을 받아들임(useCapture).
{{SpecName('DOM2 Events', 'events.html#Events-EventTarget', 'EventTarget')}}{{Spec2('DOM2 Events')}}초기 정의.
- -

브라우저 호환성

- - - -

{{Compat("api.EventTarget")}}

- -

같이 보기

- - diff --git a/files/ko/web/api/eventtarget/index.md b/files/ko/web/api/eventtarget/index.md new file mode 100644 index 0000000000..5addf5b9d6 --- /dev/null +++ b/files/ko/web/api/eventtarget/index.md @@ -0,0 +1,133 @@ +--- +title: EventTarget +slug: Web/API/EventTarget +tags: + - API + - DOM + - DOM Events + - EventTarget + - Interface + - Reference +translation_of: Web/API/EventTarget +--- +
{{ApiRef("DOM Events")}}
+ +

EventTarget은 이벤트를 받을 수 있으며, 이벤트에 대한 수신기(listener)를 가질 수 있는 객체가 구현하는 DOM 인터페이스입니다.

+ +

{{domxref("Element")}}, {{domxref("document")}} 및 {{domxref("window")}}가 가장 흔한 이벤트 대상이지만, 다른 객체, 예컨대 {{domxref("XMLHttpRequest")}}, {{domxref("AudioNode")}}, {{domxref("AudioContext")}} 등 역시 이벤트 대상이 될 수 있습니다.

+ +

많은 이벤트 대상(요소, 문서, 창, ...)은 onevent 속성과 특성을 사용한 이벤트 처리기 등록도 지원합니다.

+ +

{{InheritanceDiagram}}

+ +

생성자

+ +
+
{{domxref("EventTarget.EventTarget()", "EventTarget()")}}
+
새로운 EventTarget 객체 인스턴스를 생성합니다.
+
+ +

메서드

+ +
+
{{domxref("EventTarget.addEventListener()")}}
+
EventTarget에 특정 이벤트 유형의 이벤트 처리기를 등록합니다.
+
{{domxref("EventTarget.removeEventListener()")}}
+
EventTarget에서 주어진 이벤트 수신기를 제거합니다.
+
{{domxref("EventTarget.dispatchEvent()")}}
+
EventTarget에 이벤트를 디스패치 합니다.
+
+ + + +

예제

+ +

간단한 EventTarget 구현

+ +
var EventTarget = function() {
+  this.listeners = {};
+};
+
+EventTarget.prototype.listeners = null;
+EventTarget.prototype.addEventListener = function(type, callback) {
+  if (!(type in this.listeners)) {
+    this.listeners[type] = [];
+  }
+  this.listeners[type].push(callback);
+};
+
+EventTarget.prototype.removeEventListener = function(type, callback) {
+  if (!(type in this.listeners)) {
+    return;
+  }
+  var stack = this.listeners[type];
+  for (var i = 0, l = stack.length; i < l; i++) {
+    if (stack[i] === callback){
+      stack.splice(i, 1);
+      return;
+    }
+  }
+};
+
+EventTarget.prototype.dispatchEvent = function(event) {
+  if (!(event.type in this.listeners)) {
+    return true;
+  }
+  var stack = this.listeners[event.type].slice();
+
+  for (var i = 0, l = stack.length; i < l; i++) {
+    stack[i].call(this, event);
+  }
+  return !event.defaultPrevented;
+};
+
+ +

명세

+ + + + + + + + + + + + + + + + + + + + + + + + +
명세상태설명
{{SpecName('DOM WHATWG', '#interface-eventtarget', 'EventTarget')}}{{Spec2('DOM WHATWG')}}변화 없음.
{{SpecName('DOM3 Events', 'DOM3-Events.html#interface-EventTarget', 'EventTarget')}}{{Spec2('DOM3 Events')}}매개변수 약간이 이제 선택사항(listener) 또는 null 값을 받아들임(useCapture).
{{SpecName('DOM2 Events', 'events.html#Events-EventTarget', 'EventTarget')}}{{Spec2('DOM2 Events')}}초기 정의.
+ +

브라우저 호환성

+ + + +

{{Compat("api.EventTarget")}}

+ +

같이 보기

+ + diff --git a/files/ko/web/api/eventtarget/removeeventlistener/index.html b/files/ko/web/api/eventtarget/removeeventlistener/index.html deleted file mode 100644 index d81a32e8c9..0000000000 --- a/files/ko/web/api/eventtarget/removeeventlistener/index.html +++ /dev/null @@ -1,211 +0,0 @@ ---- -title: EventTarget.removeEventListener() -slug: Web/API/EventTarget/removeEventListener -translation_of: Web/API/EventTarget/removeEventListener ---- -

{{APIRef("DOM Events")}}

- -

EventTarget.removeEventListener() 메서드는 이전에{{domxref("EventTarget.addEventListener()")}}로 {{domxref("EventTarget")}} 에 등록했던 이벤트 리스너를 제거합니다. 이 이벤트 리스너는 이벤트 종류와 이벤트 리스너 함수 자체의 조합으로 식별되어 제거되며, 등록시 제공했던 다양한 옵션과 일치하는 이벤트 리스너만 제거할 수 있습니다.  {{anch("Matching event listeners for removal")}}를 참고하세요.

- -

Syntax

- -
target.removeEventListener(type, listener[, options]);
-target.removeEventListener(type, listener[, useCapture]);
- -

Parameters

- -
-
type
-
제거할 이벤트 리스너의 이벤트 타입을 지정합니다.
-
listener
-
이벤트 타깃에서 제거할 이벤트 핸들러 함수, {{domxref("EventListener")}}를 지정합니다.
-
options {{optional_inline}}
-
이벤트 리스너에 대한 특징, 즉 제거할 이벤트 리스너의 옵션들을 지정합니다. 지정할 수 있는 옵션들은 아래와 같습니다. -
    -
  • capture: 이 이벤트 타입의 이벤트들이 DOM 트리 내 모든 어떤 EventTarget 에 디스패치되기 전에  등록된 listener 들을 먼저 처리하도록 만들지 말지를 결정하는 {{jsxref("Boolean")}} 값.
  • -
  • {{non-standard_inline}} mozSystemGroup: Available only in code running in XBL or in Firefox' chrome, it is a {{jsxref("Boolean")}} defining if the listener is added to the system group. (비표준)
  • -
-
-
useCapture {{optional_inline}}
-
Specifies whether the {{domxref("EventListener")}} to be removed is registered as a capturing listener or not. If this parameter is absent, a default value of false is assumed.
-
If a listener is registered twice, one with capture and one without, remove each one separately. Removal of a capturing listener does not affect a non-capturing version of the same listener, and vice versa.
-
- -

Return value

- -

undefined.

- -

Matching event listeners for removal

- -

Given an event listener previously added by calling {{domxref("EventTarget.addEventListener", "addEventListener()")}}, you may eventually come to a point at which you need to remove it. Obviously, you need to specify the same type and listener parameters to removeEventListener(), but what about the options or useCapture parameters?

- -

While addEventListener() will let you add the same listener more than once for the same type if the options are different, the only option removeEventListener() checks is the capture/useCapture flag. Its value must match for removeEventListener() to match, but the other values don't.

- -

For example, consider this call to addEventListener():

- -
element.addEventListener("mousedown", handleMouseDown, true);
- -

Now consider each of these two calls to removeEventListener():

- -
element.removeEventListener("mousedown", handleMouseDown, false);     // Fails
-element.removeEventListener("mousedown", handleMouseDown, true);      // Succeeds
-
- -

The first call fails because the value of useCapture doesn't match. The second succeeds, since useCapture matches up.

- -

Now consider this:

- -
element.addEventListener("mousedown", handleMouseDown, { passive: true });
- -

Here, we specify an options object in which passive is set to true, while the other options are left to the default value of false.

- -

Now look at each of these calls to removeEventListener() in turn. Any of them in which capture or useCapture is true fail; all others succeed. Only the capture setting matters to removeEventListener().

- -
element.removeEventListener("mousedown", handleMouseDown, { passive: true });     // Succeeds
-element.removeEventListener("mousedown", handleMouseDown, { capture: false });    // Succeeds
-element.removeEventListener("mousedown", handleMouseDown, { capture: true });     // Fails
-element.removeEventListener("mousedown", handleMouseDown, { passive: false });    // Succeeds
-element.removeEventListener("mousedown", handleMouseDown, false);                 // Succeeds
-element.removeEventListener("mousedown", handleMouseDown, true);                  // Fails
-
- -

It's worth noting that some browser releases have been inconsistent on this, and unless you have specific reasons otherwise, it's probably wise to use the same values used for the call to addEventListener() when calling removeEventListener().

- -

Notes

- -

If an {{domxref("EventListener")}} is removed from an {{domxref("EventTarget")}} while it is processing an event, it will not be triggered by the current actions. An {{domxref("EventListener")}} will not be invoked for the event it was registered for after being removed. However, it can be reattached.

- -

Calling removeEventListener() with arguments that do not identify any currently registered {{domxref("EventListener")}} on the EventTarget has no effect.

- -

Example

- -

This example shows how to add a click-based event listener and remove a mouseover-based event listener.

- -
var body = document.querySelector('body'),
-    clickTarget = document.getElementById('click-target'),
-    mouseOverTarget = document.getElementById('mouse-over-target'),
-    toggle = false;
-
-function makeBackgroundYellow() {
-    'use strict';
-
-    if (toggle) {
-        body.style.backgroundColor = 'white';
-    } else {
-        body.style.backgroundColor = 'yellow';
-    }
-
-    toggle = !toggle;
-}
-
-clickTarget.addEventListener('click',
-    makeBackgroundYellow,
-    false
-);
-
-mouseOverTarget.addEventListener('mouseover', function () {
-    'use strict';
-
-    clickTarget.removeEventListener('click',
-        makeBackgroundYellow,
-        false
-    );
-});
-
- -

Specifications

- - - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName("DOM WHATWG", "#dom-eventtarget-removeeventlistener", "EventTarget.removeEventListener()")}}{{Spec2("DOM WHATWG")}} 
{{SpecName("DOM4", "#dom-eventtarget-removeeventlistener", "EventTarget.removeEventListener()")}}{{Spec2("DOM4")}} 
{{SpecName("DOM2 Events", "#Events-EventTarget-removeEventListener", "EventTarget.removeEventListener()")}}{{Spec2("DOM2 Events")}}Initial definition
- -

Browser compatibility

- -

 

- - - -

{{Compat("api.EventTarget.removeEventListener", 3)}}

- -

Polyfill to support older browsers

- -

addEventListener() and removeEventListener() are not present in older browsers. You can work around this by inserting the following code at the beginning of your scripts, allowing the use of addEventListener() and removeEventListener() in implementations that do not natively support it. However, this method will not work on Internet Explorer 7 or earlier, since extending the Element.prototype was not supported until Internet Explorer 8.

- -
if (!Element.prototype.addEventListener) {
-  var oListeners = {};
-  function runListeners(oEvent) {
-    if (!oEvent) { oEvent = window.event; }
-    for (var iLstId = 0, iElId = 0, oEvtListeners = oListeners[oEvent.type]; iElId < oEvtListeners.aEls.length; iElId++) {
-      if (oEvtListeners.aEls[iElId] === this) {
-        for (iLstId; iLstId < oEvtListeners.aEvts[iElId].length; iLstId++) { oEvtListeners.aEvts[iElId][iLstId].call(this, oEvent); }
-        break;
-      }
-    }
-  }
-  Element.prototype.addEventListener = function (sEventType, fListener /*, useCapture (will be ignored!) */) {
-    if (oListeners.hasOwnProperty(sEventType)) {
-      var oEvtListeners = oListeners[sEventType];
-      for (var nElIdx = -1, iElId = 0; iElId < oEvtListeners.aEls.length; iElId++) {
-        if (oEvtListeners.aEls[iElId] === this) { nElIdx = iElId; break; }
-      }
-      if (nElIdx === -1) {
-        oEvtListeners.aEls.push(this);
-        oEvtListeners.aEvts.push([fListener]);
-        this["on" + sEventType] = runListeners;
-      } else {
-        var aElListeners = oEvtListeners.aEvts[nElIdx];
-        if (this["on" + sEventType] !== runListeners) {
-          aElListeners.splice(0);
-          this["on" + sEventType] = runListeners;
-        }
-        for (var iLstId = 0; iLstId < aElListeners.length; iLstId++) {
-          if (aElListeners[iLstId] === fListener) { return; }
-        }
-        aElListeners.push(fListener);
-      }
-    } else {
-      oListeners[sEventType] = { aEls: [this], aEvts: [ [fListener] ] };
-      this["on" + sEventType] = runListeners;
-    }
-  };
-  Element.prototype.removeEventListener = function (sEventType, fListener /*, useCapture (will be ignored!) */) {
-    if (!oListeners.hasOwnProperty(sEventType)) { return; }
-    var oEvtListeners = oListeners[sEventType];
-    for (var nElIdx = -1, iElId = 0; iElId < oEvtListeners.aEls.length; iElId++) {
-      if (oEvtListeners.aEls[iElId] === this) { nElIdx = iElId; break; }
-    }
-    if (nElIdx === -1) { return; }
-    for (var iLstId = 0, aElListeners = oEvtListeners.aEvts[nElIdx]; iLstId < aElListeners.length; iLstId++) {
-      if (aElListeners[iLstId] === fListener) { aElListeners.splice(iLstId, 1); }
-    }
-  };
-}
-
- -

See also

- - diff --git a/files/ko/web/api/eventtarget/removeeventlistener/index.md b/files/ko/web/api/eventtarget/removeeventlistener/index.md new file mode 100644 index 0000000000..d81a32e8c9 --- /dev/null +++ b/files/ko/web/api/eventtarget/removeeventlistener/index.md @@ -0,0 +1,211 @@ +--- +title: EventTarget.removeEventListener() +slug: Web/API/EventTarget/removeEventListener +translation_of: Web/API/EventTarget/removeEventListener +--- +

{{APIRef("DOM Events")}}

+ +

EventTarget.removeEventListener() 메서드는 이전에{{domxref("EventTarget.addEventListener()")}}로 {{domxref("EventTarget")}} 에 등록했던 이벤트 리스너를 제거합니다. 이 이벤트 리스너는 이벤트 종류와 이벤트 리스너 함수 자체의 조합으로 식별되어 제거되며, 등록시 제공했던 다양한 옵션과 일치하는 이벤트 리스너만 제거할 수 있습니다.  {{anch("Matching event listeners for removal")}}를 참고하세요.

+ +

Syntax

+ +
target.removeEventListener(type, listener[, options]);
+target.removeEventListener(type, listener[, useCapture]);
+ +

Parameters

+ +
+
type
+
제거할 이벤트 리스너의 이벤트 타입을 지정합니다.
+
listener
+
이벤트 타깃에서 제거할 이벤트 핸들러 함수, {{domxref("EventListener")}}를 지정합니다.
+
options {{optional_inline}}
+
이벤트 리스너에 대한 특징, 즉 제거할 이벤트 리스너의 옵션들을 지정합니다. 지정할 수 있는 옵션들은 아래와 같습니다. +
    +
  • capture: 이 이벤트 타입의 이벤트들이 DOM 트리 내 모든 어떤 EventTarget 에 디스패치되기 전에  등록된 listener 들을 먼저 처리하도록 만들지 말지를 결정하는 {{jsxref("Boolean")}} 값.
  • +
  • {{non-standard_inline}} mozSystemGroup: Available only in code running in XBL or in Firefox' chrome, it is a {{jsxref("Boolean")}} defining if the listener is added to the system group. (비표준)
  • +
+
+
useCapture {{optional_inline}}
+
Specifies whether the {{domxref("EventListener")}} to be removed is registered as a capturing listener or not. If this parameter is absent, a default value of false is assumed.
+
If a listener is registered twice, one with capture and one without, remove each one separately. Removal of a capturing listener does not affect a non-capturing version of the same listener, and vice versa.
+
+ +

Return value

+ +

undefined.

+ +

Matching event listeners for removal

+ +

Given an event listener previously added by calling {{domxref("EventTarget.addEventListener", "addEventListener()")}}, you may eventually come to a point at which you need to remove it. Obviously, you need to specify the same type and listener parameters to removeEventListener(), but what about the options or useCapture parameters?

+ +

While addEventListener() will let you add the same listener more than once for the same type if the options are different, the only option removeEventListener() checks is the capture/useCapture flag. Its value must match for removeEventListener() to match, but the other values don't.

+ +

For example, consider this call to addEventListener():

+ +
element.addEventListener("mousedown", handleMouseDown, true);
+ +

Now consider each of these two calls to removeEventListener():

+ +
element.removeEventListener("mousedown", handleMouseDown, false);     // Fails
+element.removeEventListener("mousedown", handleMouseDown, true);      // Succeeds
+
+ +

The first call fails because the value of useCapture doesn't match. The second succeeds, since useCapture matches up.

+ +

Now consider this:

+ +
element.addEventListener("mousedown", handleMouseDown, { passive: true });
+ +

Here, we specify an options object in which passive is set to true, while the other options are left to the default value of false.

+ +

Now look at each of these calls to removeEventListener() in turn. Any of them in which capture or useCapture is true fail; all others succeed. Only the capture setting matters to removeEventListener().

+ +
element.removeEventListener("mousedown", handleMouseDown, { passive: true });     // Succeeds
+element.removeEventListener("mousedown", handleMouseDown, { capture: false });    // Succeeds
+element.removeEventListener("mousedown", handleMouseDown, { capture: true });     // Fails
+element.removeEventListener("mousedown", handleMouseDown, { passive: false });    // Succeeds
+element.removeEventListener("mousedown", handleMouseDown, false);                 // Succeeds
+element.removeEventListener("mousedown", handleMouseDown, true);                  // Fails
+
+ +

It's worth noting that some browser releases have been inconsistent on this, and unless you have specific reasons otherwise, it's probably wise to use the same values used for the call to addEventListener() when calling removeEventListener().

+ +

Notes

+ +

If an {{domxref("EventListener")}} is removed from an {{domxref("EventTarget")}} while it is processing an event, it will not be triggered by the current actions. An {{domxref("EventListener")}} will not be invoked for the event it was registered for after being removed. However, it can be reattached.

+ +

Calling removeEventListener() with arguments that do not identify any currently registered {{domxref("EventListener")}} on the EventTarget has no effect.

+ +

Example

+ +

This example shows how to add a click-based event listener and remove a mouseover-based event listener.

+ +
var body = document.querySelector('body'),
+    clickTarget = document.getElementById('click-target'),
+    mouseOverTarget = document.getElementById('mouse-over-target'),
+    toggle = false;
+
+function makeBackgroundYellow() {
+    'use strict';
+
+    if (toggle) {
+        body.style.backgroundColor = 'white';
+    } else {
+        body.style.backgroundColor = 'yellow';
+    }
+
+    toggle = !toggle;
+}
+
+clickTarget.addEventListener('click',
+    makeBackgroundYellow,
+    false
+);
+
+mouseOverTarget.addEventListener('mouseover', function () {
+    'use strict';
+
+    clickTarget.removeEventListener('click',
+        makeBackgroundYellow,
+        false
+    );
+});
+
+ +

Specifications

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName("DOM WHATWG", "#dom-eventtarget-removeeventlistener", "EventTarget.removeEventListener()")}}{{Spec2("DOM WHATWG")}} 
{{SpecName("DOM4", "#dom-eventtarget-removeeventlistener", "EventTarget.removeEventListener()")}}{{Spec2("DOM4")}} 
{{SpecName("DOM2 Events", "#Events-EventTarget-removeEventListener", "EventTarget.removeEventListener()")}}{{Spec2("DOM2 Events")}}Initial definition
+ +

Browser compatibility

+ +

 

+ + + +

{{Compat("api.EventTarget.removeEventListener", 3)}}

+ +

Polyfill to support older browsers

+ +

addEventListener() and removeEventListener() are not present in older browsers. You can work around this by inserting the following code at the beginning of your scripts, allowing the use of addEventListener() and removeEventListener() in implementations that do not natively support it. However, this method will not work on Internet Explorer 7 or earlier, since extending the Element.prototype was not supported until Internet Explorer 8.

+ +
if (!Element.prototype.addEventListener) {
+  var oListeners = {};
+  function runListeners(oEvent) {
+    if (!oEvent) { oEvent = window.event; }
+    for (var iLstId = 0, iElId = 0, oEvtListeners = oListeners[oEvent.type]; iElId < oEvtListeners.aEls.length; iElId++) {
+      if (oEvtListeners.aEls[iElId] === this) {
+        for (iLstId; iLstId < oEvtListeners.aEvts[iElId].length; iLstId++) { oEvtListeners.aEvts[iElId][iLstId].call(this, oEvent); }
+        break;
+      }
+    }
+  }
+  Element.prototype.addEventListener = function (sEventType, fListener /*, useCapture (will be ignored!) */) {
+    if (oListeners.hasOwnProperty(sEventType)) {
+      var oEvtListeners = oListeners[sEventType];
+      for (var nElIdx = -1, iElId = 0; iElId < oEvtListeners.aEls.length; iElId++) {
+        if (oEvtListeners.aEls[iElId] === this) { nElIdx = iElId; break; }
+      }
+      if (nElIdx === -1) {
+        oEvtListeners.aEls.push(this);
+        oEvtListeners.aEvts.push([fListener]);
+        this["on" + sEventType] = runListeners;
+      } else {
+        var aElListeners = oEvtListeners.aEvts[nElIdx];
+        if (this["on" + sEventType] !== runListeners) {
+          aElListeners.splice(0);
+          this["on" + sEventType] = runListeners;
+        }
+        for (var iLstId = 0; iLstId < aElListeners.length; iLstId++) {
+          if (aElListeners[iLstId] === fListener) { return; }
+        }
+        aElListeners.push(fListener);
+      }
+    } else {
+      oListeners[sEventType] = { aEls: [this], aEvts: [ [fListener] ] };
+      this["on" + sEventType] = runListeners;
+    }
+  };
+  Element.prototype.removeEventListener = function (sEventType, fListener /*, useCapture (will be ignored!) */) {
+    if (!oListeners.hasOwnProperty(sEventType)) { return; }
+    var oEvtListeners = oListeners[sEventType];
+    for (var nElIdx = -1, iElId = 0; iElId < oEvtListeners.aEls.length; iElId++) {
+      if (oEvtListeners.aEls[iElId] === this) { nElIdx = iElId; break; }
+    }
+    if (nElIdx === -1) { return; }
+    for (var iLstId = 0, aElListeners = oEvtListeners.aEvts[nElIdx]; iLstId < aElListeners.length; iLstId++) {
+      if (aElListeners[iLstId] === fListener) { aElListeners.splice(iLstId, 1); }
+    }
+  };
+}
+
+ +

See also

+ + -- cgit v1.2.3-54-g00ecf