최종 수정 : 2024-04-06
연결 지식
이벤트 전파(event propagation)
https://young-taek.tistory.com/213
1. 이벤트 위임(event delegation)
캡처링과 버블링을 활용하면 강력한 이벤트 핸들링 패턴인 이벤트 위임(event delegation)을 구현할 수 있다. 비슷한 방식으로 여러 요소를 다뤄야 할 때 사용한다. 이벤트 위임을 사용하면 핸들러를 할당하지 않고, 요소의 공통 조상에 이벤트 핸들러를 단 하나만 할당해도 여러 요소를 한꺼번에 다룰 수 있다.
장점
1. 많은 핸들러를 할당하지 않아도 되기 때문에 초기화가 단순해지고 메모리가 절약된다.
2. 요소를 추가하거나 제거할 때 해당 요소에 할당된 핸들러를 추가하거나 제거할 필요가 없어져 코드가 짧아진다.
3. innerHTML 이나 유사한 기능을 하는 스크립트로 요소 덩어리를 더하거나 뺄 수 있어서 DOM 수정이 쉬워진다.
단점
이벤트 위임을 사용하려면 이벤트가 반드시 버블링 되어야 한다.
<div class="menu">
<button class="menu-btn" data-value="1">
<span class="btn-label">버튼 1</span>
</button>
<button class="menu-btn" data-value="2">
<span class="btn-label">버튼 2</span>
</button>
<button class="menu-btn" data-value="3">
<span class="btn-label">버튼 3</span>
</button>
</div>
버튼에 각각 이벤트 핸들러를 작성하여 처리하는 방법은 메모리 낭비나 다름없다. 이보다는 버튼들의 부모 요소에 이벤트 리스너를 연결하여 자식 요소로 있는 버튼들이 동작하도록 연결(바인딩)하는 방식으로 처리할 수 있다.
[방법 1]
버튼 안 요소(span)이 이벤트 영향을 받지 않게 만들어서, 버튼만 동작하도록 하기
/* 방법 1)
이벤트 영향을 받지 않게끔 설정해주는 CSS
- 하위에 있는 요소를 타깃으로 잡을 수 없다는 것을 유념해야 한다.*/
.btn-label {
pointer-events: none;
}
[방법 2-1]
스크립트 활용
const $menu = document.querySelector('.menu');
function clickHandler(e) {
let elem = e.target;
// div 태그(menu)의 자식 요소가 얼마나 있을지 모르기 때문에 while문으로 작성
while (!elem.classList.contains('menu-btn')) {
elem = elem.parentNode;
// 버튼 영역 바깥을 클릭했을 때, 종료
if (elem.nodeName == "BODY") {
elem = 'null';
return;
}
}
}
$menu.addEventListener('click', clickHandler);
[방법 2-2]
스크립트를 동적으로 활용
이는 부모요소에 이벤트 위임을 했기 때문에 가능한 것이다. div(menu)의 자식 요소로 생성한다.
<body>
<div class="menu">
<!-- 여기에 버튼에 대한 코드가 생기는 것과 같다. -->
</div>
<script>
const $menu = document.querySelector('menu');
function clickHandler(e) {
let elem = e.target;
while (!elem.classList.contains('menu-btn')) {
elem = elem.parentNode;
if (elem.nodeName == "BODY") {
elem = 'null';
return;
}
}
}
$menu.addEventListener('click', clickHandler);
window.addEventListener('click', () => {
const htmlStr = `
<button class="menu-btn" data-value="1">
<span class="btn-label">버튼 1</span>
</button>
<button class="menu-btn" data-value="2">
<span class="btn-label">버튼 2</span>
</button>
<button class="menu-btn" data-value="3">
<span class="btn-label">버튼 3</span>
</button>
`;
$menu.innerHTML = htmlStr;
});
</script>
</body>
+) 추가 공부 필요
matches 메서드 활용
참고 자료
https://ko.javascript.info/event-delegation
이벤트 위임을 처리하는 방법
'프론트엔드 > JS 공부' 카테고리의 다른 글
객체 - 배열 - 문자열의 상관 관계 (0) | 2024.04.26 |
---|---|
HTTP 메서드(method)에 대한 정리 (0) | 2024.04.06 |
생성자 함수(constructor)에 대한 정리 (1) | 2024.04.05 |
이벤트 전파(Event propagation)에 대한 정리 (0) | 2024.04.05 |
Map() 객체에 대한 정리 (0) | 2024.04.04 |
댓글