-
TIL-2024.03.19 - JS - 이벤트 버블링 & 캡처링> 기초/Javascript 2024. 3. 19. 20:57
목표:
- 이벤트 캡처링
- 이벤트 버블링
- 이벤트 캡처링과 버블링 막는 방법
이벤트 캡처링(Event Capturing):
- 캡처링은 이벤트가 DOM 트리의 상위 요소에서 하위 요소로 향하는 단계 (상위 > 하위)
- 이벤트가 발생한 요소의 부모 요소부터 시작하여 해당 요소의 가장 최상위 요소인 document까지 이벤트가 전파.
- 예를 들어, 버튼 요소를 클릭하면, 이 클릭 이벤트는 가장 상위 요소인 document까지 전파되는데, 이 단계에서 이벤트는 이벤트 리스너에 의해 캡처링 단계에서 포착될 수 있습니다.
// index.html <div id="outer"> <div id="inner"> <button id="button">Click me</button> </div> </div> // main.js document.getElementById('outer').addEventListener('click', function(){ console.log('캡처링 단계: Outer div'); }, true); document.getElementById('inner').addEventListener('click', function(){ console.log('캡처링 단계: Inner div'); }, true); document.getElementById('button').addEventListener('click', function(){ console.log('캡처링 단계: Button'); }, true); // 캡처링 단계: Outer div // 캡처링 단계: Inner div // 캡처링 단계: Button
이벤트 버블링(Event Bubbling):
- 버블링은 이벤트가 발생한 요소에서 상위 요소로 향하는 단계. (하위 > 상위)
- 캡처링과 반대로, 이벤트가 가장 하위 요소에서 시작하여 부모 요소로 이동.
- 캡처링 단계 이후에 발생하며, 이벤트가 발생한 요소를 포함한 모든 부모 요소까지 이벤트가 전파.
// index.html <div id="outer"> <div id="inner"> <button id="button">Click me</button> </div> </div> // main.js document.getElementById('outer').addEventListener('click', function(){ console.log('캡처링 단계: Outer div'); }, true); document.getElementById('inner').addEventListener('click', function(){ console.log('캡처링 단계: Inner div'); }, true); document.getElementById('button').addEventListener('click', function(){ console.log('캡처링 단계: Button'); }, true); document.getElementById('outer').addEventListener('click', function(){ console.log('버블링 단계: Outer div'); }); document.getElementById('inner').addEventListener('click', function(){ console.log('버블링 단계: Inner div'); }); document.getElementById('button').addEventListener('click', function(){ console.log('버블링 단계: Button'); }); 캡처링 단계: Outer div 캡처링 단계: Inner div 캡처링 단계: Button 버블링 단계: Button 버블링 단계: Inner div 버블링 단계: Outer div
이벤트 캡처링과 버블링 막는 방법:
1. preventDefault() 메서드 사용 > 기본 동작을 취소하는 데 사용
... 중략 ... <body> <div> <a href="https://naver.com" id="naver-link">네이버</a> </div> </body> <script> document.querySelector("#naver-link").addEventListener("click", (e) => { e.preventDefault(); console.log("preventDefault로 네이버로 이동안하고 console 만 찍어줌!") }); </script> ... 중략 ...
2. stopPropagation() 메서드 사용 > 상위 요소가 이벤트를 감지할 수 없고 이벤트리스너가 가르키고 있는 요소만 이벤트를 감지
... 중략 ... <body> <div class="div-container"> <div class="div-button" style="cursor: pointer">날 눌러보소</div> </div> </body> <script> document.querySelector(".div-button").addEventListener("click", (e) => { alert(".div-button 클릭!"); }); document.querySelector(".div-container").addEventListener("click", (e) => { alert("body 클릭!"); }); </script> ... 중략 ...
1. 위의 예제에서 .div-container .div-button 에 각각 click 이벤트 리스너를 할당
2. 날 눌러보소 라는 div tag 클릭한 경우, 아래의 두장의 사진과 같이 이벤트 버블링이 발생해서 두개의 alert 문 실행
3. 아래의 코드와 같이 e.stopPropagation() 을 사용하면, 해당 요소의 이벤트만 감지
document.querySelector(".div-button").addEventListener("click", (e) => { e.stopPropagation(); alert(".div-button 클릭!"); }); document.querySelector(".div-container").addEventListener("click", (e) => { e.stopPropagation(); alert("body 클릭!"); });
3. 캡처링에서만 막기:
document.getElementById('button').addEventListener('click', function(event){ event.stopPropagation(); // 버블링을 막음 }, true); // addEventListener의 세 번째 매개변수를 true로 설정하여 이벤트 캡처링 단계에서만 동작하도록 만들고, 그 안에서 stopPropagation()을 호출합니다.
'> 기초 > Javascript' 카테고리의 다른 글
TIL-2024.03.24 - JS - 얕은 복사 & 깊은 복사 (0) 2024.03.24 TIL-2024.03.22 - JS - Closure (0) 2024.03.22 TIL-2024.02.27 - JS - 실행 컨텍스트-4. 렉시컬 환경-3 (0) 2024.02.27 TIL-2024.02.26 - JS - 실행 컨텍스트-3. 렉시컬 환경-2 (0) 2024.02.26 TIL-2024.02.25 - JS - MAP과 예제 (1) 2024.02.25