이벤트(event)란 여러분이 프로그래밍하고 있는 시스템에서 일어나는 사건(action) 혹은 발생(occurrence)인데, 이는 여러분이 원한다면 그것들에 어떠한 방식으로 응답할 수 있도록 시스템이 말해주는 것입니다.
-mdn
event에 대한 mdn의 설명은 위와 같다.
저 설명을 바탕으로 javascript, 특히 웹에서의 event가 무엇인지 생각해보았다.
event는 브라우저 내의 DOM 요소에 발생하는 사건이고, 브라우저는 이것을 감지해서 사용자와의 상호작용을 만들어낸다.
위에서 event는 브라우저 내의 특정 DOM요소에 발생한다고 했는데, 이처럼 이벤트가 발생한 대상 객체를 Event.target이라고 한다.
우리가 자주 마주하는 DOM 구조를 생각해보면 요소 안에 요소가 위치하는 식으로 계층적인 구조를 이루고 있다.
그래서 위 그림과 같이 이벤트도 제일 아래에 있는 요소까지 계층적으로 발생하게 된다.
(책상위에 여러 물건을 쌓아두고 맨 위를 눌렀을 때를 대입해보면 이해가 쉽다.)
이러한 현상을 event propagation이라고 하고, capturing, target, bubbling의 3단계로 이벤트 전파 흐름이 생긴다.
기본적으로는 bubbling 순서로 이벤트가 감지 되는데, capturing 단계에서 이벤트를 감지하려면 addEventListener메서드의 3번째 인자에 값을 true로 주면 된다.
이제 이벤트를 이용해서 상호작용을 만들어내는 방법을 알아보자.
event의 흐름을 이해했다면 이벤트를 잡아내는 방법이 궁금할 것이다.
여러 방법이 있는데 결론부터 말하자면 event listener를 사용하는 것을 권장한다.
다양한 event중 click event를 감지하는 여러가지 방법을 비교해보겠다.
const btn = document.querySelector("button");
function click() {
console.log("clicked")
}
btn.onclick = click;
btn이라는 요소를 DOM에서 찾아내서 onclick 프로퍼티에 click이라는 함수를 등록한다.
이렇게 하면 btn이 클릭되었을 때 click함수가 실행된다.
mdn 문서를 보면 아래와 같이 경고를 한다.
html과 js를 분리하지 않으면 코드를 분석하기 어렵고, 100개의 버튼에 100개의 어트리뷰트를 더한다면 유지보수가 불가능에 가깝기 때문에 이 방법은 쓰지말라고 한다.
const btn = document.querySelector("button");
function click() {
console.log("clicked")
}
btn.addEventListener("click", click);
가장 권장되는 방식인데, 말 그대로 event를 기다리고 있다가 event가 발생하면 콜백함수를 실행해준다.
다른 방식과 비교했을 때 몇몇 이점을 가지고 있다.
btn.removeEventListener("click", click);
결국 이벤트 핸들러도 메모리를 사용하기 때문에 사용하지 않는 이벤트 핸들러를 제거할 수 있다는 것은 큰 장점이다.
주의할 점은 콜백함수의 이름을 찾아서 제거하는 것이기 때문에 콜백함수를 기명함수로 써야한다는 것이다.
myElement.onclick = functionA; // functionB로 덮어 씌워짐
myElement.onclick = functionB;
myElement.addEventListener("click", functionA);
myElement.addEventListener("click", functionB);
Event.target와 비슷한 Event.currentTarget이 있는데 currentTarget과 target은 다를 수도 있고, 같을 수도 있다.
target은 이벤트가 발생하는 요소,
currentTarget은 이벤트 핸들러가 부착된 요소다.
헷갈린다면 이벤트 캡쳐링과 버블링을 다시보자.
이벤트 위임에 대해서 정리하기위해 이벤트에 대한 개념들을 쓰다보니 양이 아주 많아졌다...
이벤트 위임은 다음 글에 써야할 것 같다 😁