이벤트 캡처링과 버블링
이벤트는 캡처링단계와 버블링 단계를 밟으며 감지가 됩니다.
JSFiddle 내부 Result 탭에서 box나 button을 누르면 alert기능이 캡처링과 버블링 과정을 거치며 발생합니다.
발생할 때마다 모든 요소에 alert기능을 집어넣었기 때문에
Button을 자칫 클릭하실 경우 alert를 10번이나 누르셔야 하니 주의하시기 바랍니다 ㅋㅋ
가장 내부의 Button을 클릭하면 발생하는 일은
body -> html -> form -> div -> button 순으로 캡처링이 발생하고,
button -> div -> form -> html -> body 캡처링과 역순으로 버블링이 발생합니다.
el.addEventListener('click', () => alert(`capturing: ${el.tagName}`), true);
el.addEventListener('click', () => alert(`bubbling: ${el.tagName}`));
이벤트 리스너에서 콜백함수 이후에 true를 작성하면 이벤트 캡처링이,
아무것도 지정하지 않는 경우 (default false) 이벤트 버블링이 발생합니다.
가장 내부의 있는 요소로부터 가장 외부의 있는 요소까지 캡처링 과정과 버블링 과정을 통해
이벤트가 전달, 전달, 전달... 전달이 됩니다.
event.target & event.currentTarget
event 에는 target 속성이 있습니다.
이 target 속성은 이벤트가 발생한 대상 객체를 가리킵니다.
event.target 을 이용하면 어떤 대상이 이벤트가 발생했는지 정확하게 알 수 있습니다.
event 에는 currentTarget 속성도 있는데, event가 달려있는 요소를 말합니다.event 에는 target이 이벤트가 발생한 가장 내부에 있는 것을 대상으로 객체를 가르키기 때문에 currentTarget 과 target이 다를 수 있습니다.
위의 소개해드린 세가지 특징 이벤트 캡처링, 버블링의 특징과 event.target을 통해 이벤트 위임을 진행할 수 있습니다.
이벤트 위임 (event delegation)
👻 코딩 악귀가 달라붙은 예제
이벤트 위임을 하지않고 개별 버튼들에 이벤트리스너를 하나하나 달아준 예시입니다.
요즘은 컴퓨터들이 너무 좋아서 단지 몇개의 버튼들로는 별 의미는 없지만
만약 다른 예시에서 수백 개, 수천 정도의 이벤트 리스너를 다는 경우
이벤트 리스너를 다는데에만 저 코드때문에 시간적 손실이 발생하며 이는 곧 성능 저하로 연결됩니다.
위에서 언급한 세 가지 특징들을 이용해 이벤트를 부모 요소에서 감시하는 것으로 자식 요소에 전가시킬 수 있습니다.
🕺코딩의 신이 어루만지는 예제
아래 예시는 forEach 문을 통해 각각의 버튼들을 넣지 않고,
div 한 가지 태그에 딱 한 번만 리스너를 만드는 모습입니다.
event.currentTarget 은 div가 되지만, event.target은 그 내부 요소들 button들에서 이벤트가 발생하면
그것을 타깃으로 이벤트를 전가할 수 있습니다.
다만 이 코드에서는 event.target이 div일 때 (button 외부 여백에 클릭 시, event.currentTarget과 event.target이 같은 경우)
외부 여백이 이벤트가 발생하여 색상이 변하는 것을 확인할 수 있습니다.
이러한 경우를 방지하기 위해 보통 추가 코드를 작성합니다.
위 경우는 div박스에서 발생한 이벤트가 달아준 이벤트랑 동일한 경우에는
아래 코드로 이어지지 않고 바로 리턴시킨 경우입니다.
이런식으로 이벤트 리스너를 똑같은 걸 여러개 달아줘야 하는 경우엔
이벤트 위임을 달아주는 코드를 작성하는것이 좋습니다.
'웹 (프론트엔드 취준 당시 공부했던 글) > Javascript' 카테고리의 다른 글
자바스크립트에서 함수 (function)를 정리해보자 - 1 (0) | 2023.01.16 |
---|