위 글에서 document.addEventListener는 document 내부에 있는 모든 요소에 대해 반응함을 알 수 있음. document 이벤트가 내부의 <p>요소와 <input type="button">요소의 이벤트에 반응했던 이유는 이벤트 위임(Event Delegation) 때문.
1. 이벤트의 발생 단계
https://ko.javascript.info/bubbling-and-capturing
1. 캡처링 단계(Capture Phase): 이벤트가 DOM tree 하위 노드로 전파되는 단계
위와 같은 코드를 실행해보면 각 요소에 대한 event listener를 어떤 식으로 배치하던간에 이벤트 버블링이 일어나기 때문에 하위 노드 이벤트 → 상위 노드 이벤트 순으로 발생함. 이때, 이벤트 캡처링/버블링이 발생하는 노드는 window → ... → 부모 노드 → 타겟 노드이고, 자식 노드, 형제 노드, 위계구조 바깥의 노드는 이벤트 캡처링/버블링과 관련이 없음에 주의!
2.event.target 과 event.currentTarget
이벤트 발생 단계에 의해 event.target과 event.currentTarget가 가리키는 요소는 아래와 같음.
① event.target: 실제로 이벤트가 발생한 요소(타겟 요소) ② event.currentTarget: 이벤트 핸들러가 할당된 요소
이벤트 위임(Event Delegation)
2022.03.07 - [HTML, CSS] - (2022. 3. 7.) document.addEventListener()
위 글에서 document.addEventListener는 document 내부에 있는 모든 요소에 대해 반응함을 알 수 있음. document 이벤트가 내부의 <p>요소와 <input type="button">요소의 이벤트에 반응했던 이유는 이벤트 위임(Event Delegation) 때문.
1. 이벤트의 발생 단계
1. 캡처링 단계(Capture Phase): 이벤트가 DOM tree 하위 노드로 전파되는 단계
※ addEventListener의 capture 옵션 기본값이 false이므로 캡처링 단계에서는 이벤트 발생되지 않음
2. 타겟 단계(Target Phase): 이벤트가 실제 타겟 노드에 전달되는 단계 * 타겟 이벤트 리스너 실행됨 *
3. 버블링 단계(Bubbling Phase): 이벤트가 DOM tree 상위 노드로 전파되는 단계
※ 타겟 요소의 모든 부모 요소에게 이벤트가 순차적으로 전파됨
위와 같은 코드를 실행해보면 각 요소에 대한 event listener를 어떤 식으로 배치하던간에 이벤트 버블링이 일어나기 때문에 하위 노드 이벤트 → 상위 노드 이벤트 순으로 발생함. 이때, 이벤트 캡처링/버블링이 발생하는 노드는 window → ... → 부모 노드 → 타겟 노드이고, 자식 노드, 형제 노드, 위계구조 바깥의 노드는 이벤트 캡처링/버블링과 관련이 없음에 주의!
2.event.target 과 event.currentTarget
이벤트 발생 단계에 의해 event.target과 event.currentTarget가 가리키는 요소는 아래와 같음.
예를 들어, <p> 요소(p1)에서 클릭 이벤트가 발생했을 때
① event.target: <p>
② event.currentTarget: <p>
① event.target: <p>
② event.currentTarget: document
3. 이벤트 위임(Event Delegation)
이벤트 위임은 상위 요소에서 하위 요소의 이벤트를 제어하는 방식으로, ① 특정 요소의 여러 하위 요소의 이벤트를 비슷하게 다루는 경우, ② 동적으로 생성되는 하위 요소에 대한 이벤트를 다루는 경우에 유용하게 쓰일 수 있음
하위 노드에서 클릭 이벤트가 발생했을 때...
1. 캡처링(Capturing): 상위 노드에서 이벤트 발생 → 하위 노드에서 이벤트 발생
2. 버블링(Bubbling): 하위 노드에서 이벤트 발생 → 상위 노드에서 이벤트 발생
A. 이벤트 위임의 활용
1. 상위 요소에 대한 event handler로 이벤트가 발생한 하위 요소 선택하기
요소 thisParent 내부의 class가 thisClass인 요소 child에서 클릭 이벤트가 발생하면, 요소 child를 포함한 상위 요소 <label>를 요소 otherParent로 이동시키는 함수
① thisParent 내부의 임의의 요소에서 클릭 이벤트가 발생하면 이벤트 타겟(e.target)이 내가 원하는 요소가 아닐 수 있으므로 matches() 메서드를 이용해서 검사
② thisParent 내부의 class가 thisClass인 child를 찾아서
③ 조건에 부합하는 요소가 존재하면 child를 otherParent로 이동
※ child가 문서 로드 이후에 동적으로 생성되는 객체라도 해당 객체를 이동시킬 수 있음
B. 이벤트 위임과 관련된 유용한 메서드
1. Node.parentNode #
해당 Node의 바로 상위 요소를 반환
※ 객체 Element는 Node의 하위 객체이므로 Element에 대해서도 적용 가능함
2. Element.closest('selector') #
해당 Element의 부모 요소 중 selector와 일치하는 요소를 상위 방향으로 탐색하여 반환
3. Element.matches('selector') #
해당 Element가 selector와 일치하는지 여부를 반환
4. Node.contains(Node) #
해당 노드가 주어진 인자 Node를 자손으로 가지는지 여부를 반환(자기 자신일 경우에도 true 반환)
[참고]
[JavaScript] 이벤트 위임
[JS] 이벤트 전파와 이벤트 위임
Javascript delegate for elements with child nodes
'JavaScript' 카테고리의 다른 글