일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 러닝 자바스크립트
- 함수
- ES6
- 우아한테크코스
- 토이 프로젝트
- 회고의 회고
- 개인 프로젝트
- 리액트
- html
- AWS
- 주간 회고
- 자바스크립트
- 우아한형제들
- 우아한테크캠프
- 프로그래머스
- 알고리즘
- express
- toast
- 자바
- 네이버 테크 콘서트
- CSS
- 레인지 슬라이더
- 토이프로젝트
- Hello Coding HTML5+CSS3
- 우아한테크캠프 4기
- 모듈 배포하기
- npm
- 자바스크립트 객체
- 인사이드 자바스크립트
- 코드스쿼드
- Today
- Total
블로그
이벤트 버블링, 캡쳐, 위임 본문
자바스크립트는 웹 API를 통해 사용자의 입력 (클릭, 커서 이동, 키 입력 등) 에 따른 추가 동작을 구현한다.
그리고 브라우저는 버블링과 캡쳐링을 통해 이벤트를 감지한다.
이벤트 버블링
이벤트 버블링은 하위에서 상위 요소로 이벤트를 전달하는 특성이다.
버블링은 기본적으로 최상위 태그인 body까지 이벤트를 전달한다.
<div class="a">
a
<div class="b">
b
<div class="c">
c
<div class="d">
d
</div>
</div>
</div>
</div>
<script>
const a = document.querySelector('.a');
a.addEventListener('click', () => alert('a'));
</script>
위의 이미지와 같은 a > b > c > d 형태의 구조로 코드를 작성했다.
이후 a를 대상으로 클릭 이벤트를 생성하면 b나 c, d의 영역을 클릭해도 해당 이벤트가 발생한다.
이는 d에서 이벤트가 발생했을 때, 최상위에 있는 요소까지 이벤트를 전파하기 때문이며, 이를 이벤트 버블링이라 한다.
버블링을 막는 방법으로는 stopPropagation() 과 상위 태그의 이벤트에서 bubbles 프로퍼티를 검사하는 방법이 있다.
const a = document.querySelector('.a');
const d = document.querySelector('.d');
// stopPropagation
a.addEventListener('click', e => {
alert('a'));
}
d.addEventListener('click', e => {
e.stopPropagation();
}
// bubbles
a.addEventListener('click', e => {
if(e.bubbles) return;
alert('a');
});
d.addEventListener('click', e => {
});
이벤트 캡쳐
이벤트 캡쳐는 버블링과는 반대로 하위 요소로 이벤트를 전달하는 특성이다.
버블링과 마찬가지로 최상위 태그인 body부터 해당 태그를 찾아가게 된다.
const div = document.querySelectorAll('div');
div.forEach(v => v.addEventListener('click', e => {
alert(e.currentTarget.className);
}, { capture : true }));
html의 구조는 버블링과 동일하다.
캡쳐는 버블링과 다르게 addEventListener에 추가적인 설정이 필요하다.
세 번째 인자인 options에 capture : true 를 설정하면 된다.
위의 코드에서 a, b, c, d 모든 태그에 이벤트를 생성했으며, 이제 d를 클릭하게 되면 상위 태그인 a부터 이벤트가 발생하게 된다.
버블링으로 구현했다면 d, c, b, a 순으로 alert가 발생하겠지만
캡처로 구현했으므로 a, b, c, d의 순서로 alert가 발생한다.
이벤트 위임
ul 태그가 있고 하위의 li태그는 클릭 시 textContent를 console에 출력한다고 할 때,
li태그에 이벤트를 추가한다면, 새로운 li태그가 추가됐을 때, 새로운 태그에 또 이벤트를 생성해야하므로 번거로우며, 불필요한 메모리 사용이 발생한다.
하지만 ul 태그 하나에 이벤트를 추가한다면, 버블링의 특성을 통해 하위 요소인 li의 변화와 상관없이 공통적인 이벤트를 관리할 수 있게 된다.
// 일반
const li = document.querySelectorAll('li');
li.forEach(v => v.addEventListener('click', e => console.log(e.target.textContent)));
// li가 추가된다면?
const newLi = li[li.length - 1];
newLi.addEventListener('click', e => console.log(e.target.textContent));
// 위임
const ul = document.querySelector('ul');
ul.addEventListener('click', e => {
if(e.target.tagName === 'LI')
console.log(e.target.textContent);
});
// li가 추가돼도 상관없음!
출처
https://developer.mozilla.org/en-US/docs/Web/API/Event/bubbles
'자바스크립트' 카테고리의 다른 글
웹팩 기초, 로더 (0) | 2021.07.15 |
---|---|
TypeScript - 1 환경설정, 기본타입 (0) | 2021.04.03 |
this (0) | 2021.03.20 |
[메모 트리 프로젝트] 4. UI 구현 - 1 (0) | 2021.03.18 |
Express 메모 (cors, ESM, path, ejs) (0) | 2021.03.18 |