HTML DOM 이벤트 리스너

박종한·2020년 3월 10일
0

DOM

목록 보기
8/12

addEventListener

addEventListener() method는 특정 요소에 이벤트 핸들러를 부착시킵니다.
기존의 이벤트 핸들러를 덮어쓰지 않고, 부착시켜줍니다.

하나의 요소에 많은 이벤트 핸들러를 추가할 수 있습니다.
즉, 하나의 요소에 같은 타입의 핸들러를 추가할 수 있다는 얘기입니다.(두개의 클릭이벤트)
어떤 DOM 객체든지 간에, 이벤트 핸들러를 추가해줄 수 있습니다.

addEventListener() method는 이벤트가 어떻게 반응해야 하는가에 대한 제어를 쉽게 해줍니다.

element.addEventListener(event, function, useCapture);

문법은 위와 같습니다.

첫번째 파라미터인 event는 이벤트의 타입을 말합니다.("click", "mousedown" 같은 HTML DOM 이벤트)
두번째 파라미터인 function은 우리가 이벤트 발생시 부르고자 하는 함수를 넘겨줍니다.
마지막으로 세번째 파라미터는 필수가 아닌, 옵션이고, event bubbling을 사용할지, event capturing을 사용할지에 대한 boolean value입니다.

event bubbling과 event capturing은 조금 이따가 다루겠습니다.


예문을 하나하나 적어보겠습니다.

document.getElementById("myBtn").addEventListener("click", displayDate);

myBtn이란 아이디를 가진 HTML 요소를 가지고 온 후, 클릭시에 이벤트가 발생하도록 하고, 이벤트 발생시 displayDate라는 함수를 부르게 됩니다.

element.addEventListener("click", myFunction);

function myFunction() {
  alert ("Hello World!");
}

이런식으로도 말이지요. element는 HTML element입니다.

element.addEventListener("click", myFunction);
element.addEventListener("click", mySecondFunction);

위에도 적었지만, 동일한 HTML 요소에, 또 똑같은 타입의 핸들러를 추가할 수 있습니다.
위에 보이는 함수들은 alert창을 띄우는 두 개의 함수인데, 둘다 실행이 됩니다.

element.addEventListener("mouseover", myFunction);
element.addEventListener("click", mySecondFunction);
element.addEventListener("mouseout", myThirdFunction);

물론 이런식으로 똑같은 요소에 다양한 타입의 이벤트도 역시나 추가해줄 수 있습니다.


Window Object

이벤트리스너 method는 어떤 HTML DOM 객체든지 간에 이벤트 리스너를 추가할 수 있다고 하였습니다. HTML 문서, window 객체 같은 것들도 말이죠.

window.addEventListener("resize", function(){
  document.getElementById("demo").innerHTML = sometext;
});

위 코드는 현재 브라우저의 창이 조절될때 마다 어떤 값이 demo라는 아이디를 가지는 요소에 출력하는 코드입니다.

sometext부분에 Math.random()를 넣는다면, 윈도우창이 바뀔때마다 계속해서 랜덤한 값이 출력되겠죠.

const p1 = 5;
const p2 = 7;
element.addEventListener("click", function(){ myFunction(p1, p2); });

물론 매개변수로 함수를 호출하는 방법도 있지만, 익명함수로 이렇게 그냥 함수 자체를 파라미터안에 작성해주는 방법도 있고, 또 그 익명함수 안에서 다른 함수를 부르는 방법도 있습니다.

Event Bubbling or Event Capturing

아까 나중에 다루겠다고 한 부분인데,
HTML DOM에 대한 이벤트 전파의 방법이 두 가지가 있습니다. 바로 버블링과 캡쳐링입니다.

이벤트 전파는 이벤트가 발생할 때 요소 순서를 정의하는 방법입니다.
<p>요소가 <div>안에 있다고 가정해봅시다. <p> 요소를 클릭한다면, 어떤 요소의 "click" 이벤트가 먼저 처리되어야 할까요?

버블링에선, 안의 것이 가장 먼저 처리가 됩니다. 즉, 바깥의 것이 가장 나중에 처리됩니다. 마치 블록 스코프 같은 느낌이죠.

캡쳐링에선 반대로 바깥에것이 먼저 실행됩니다. 보통 프로그래밍 코드를 짜면, 안쪽보다 바깥쪽이 먼저 실행되는 것과 비슷한 맥락입니다.

아까 addEventListener함수에서

element.addEventListener(event, function, useCapture);

이 부분에서 useCapture를 생략하지 않고, true로 하게 된다면, 바깥 요소부터 먼저 이벤트가 처리될 것입니다. 초기값은 false인데, 이말은 즉, 우리가 보통은 버블링으로 이벤트 전파를 하고 있다는 얘기가 됩니다.

요약 : 우리가 평상시에 쓰는건 bubbling이고 세번째 매개변수로 true를 주면 capturing입니다. 바깥->안 순서로 이벤트가 처리되면 capturing, 안->바깥 순서로 이벤트가 처리되면 bubbling 입니다.
removeEventListener(event, function);

이렇게 하면 아까 넣어줬던 이벤트 핸들러 함수(function)과 이벤트 리스너가 사라집니다.

Cross Browser Solution

addEventListener()와 removeEventListener()는 IE 8과 그 이전 버전에선 지원하지 않습니다. 보통 한국인이라면, 아니 전세계 사람이라면 크롬이 대중화 되기전까진 익스플로러를 쓰는게 굉장히 스탠다드였는데요. 마이크로소프트가 혼자 이렇게 독자적으로 뭔가를 구축해서 불편하게 하고있단걸 컴퓨터 전공하고 나서야 알았네요..

그런 지원되지 않는 브라우저 버전을 위해 attachEvent(), detachEvent()를 사용할 수 있습니다.

var x = document.getElementById("myBtn");
if (x.addEventListener) {     // For all major browsers, except IE 8 and earlier
  x.addEventListener("click", myFunction);
} else if (x.attachEvent) {   // For IE 8 and earlier versions
  x.attachEvent("onclick", myFunction);
}

이런식으로 해주면 IE 8과 그전 버전을 제외하면 if로, IE 8과 그전버전은 else if로 들어가게 되어 모든 브라우저에서 처리해줄 수 있게됩니다.

뒤에 "click" 부분만 "onclick"으로 고쳐주면 되겠네요.

profile
코딩의 고수가 되고 싶은 종한이

0개의 댓글