[3주차] JavaScript - 이벤트의 버블링과 캡처링

minLuna·2023년 3월 18일
0

엘리스 AI트랙 7기

목록 보기
18/62

본 자료는 박규하 코치님과 Elice 플랫폼의 자료를 사용하여 정리하였습니다.

이벤트의 개념과 종류

  • 이벤트란 웹페이지에서 발생하는 사건을 의미
  • 마우스 클릭, 키보드 입력, 스크롤 등등...

이벤트 핸들러와 이벤트 모델

이벤트 핸들러

  • 이벤트가 발생했을 때 실행되는 함수나 코드조각
  • 방식
    • 인라인 방식 - HTML요소에 직접 지정
    • 전통적 방식 - 자바스크립트에서 할당
    • 표준 방식 - addEventListener 메소드를 사용
window.onload = function() {
    var text = document.getElementById("text");
    text.innerHTML = "HTML 문서가 로드되었습니다.;

이벤트 핸들러 등록

  • btn.addEventListener(event, handler);

이벤트 모델

  • 여러 요소에 동일한 이벤트가 발생했을 때 어떻게 처리되는지 정하는 규칙
  • 표준 방식에서는 addEventListener 메소드의 세번째 인자로 선택할 수 있다.

addEventListener(event, handler, [options])

# HTML 속성에 핸들로 할당
<input type = "button" onclick = "countRabbits()" value = "토끼를 세봅시다!“ />
<script>
    function countRabbits() {
        for (let i = 1; i <= 3;i++) {
            alert(`토끼 ${i} 마리`);
        }
    }
</script>
  • 위 코드의 문제점은 복수의 핸들러 할당이 불가능하고 addEventListener를 써야 감지할 수 있는 이벤트가 있다.
<input type = "button" onclick = "countRabbits()" value = "토끼를 세봅시다!“ />
<script>
    document.getElementById("elem").onclick = function () {
        alert("덮어씌움!!);
    };
</script>

addEventListener의 event 종류

  • 마우스
  • click
  • contextmenu
  • mouseover / mouseout
  • mousedown / mouseup
  • mousemove
  • 폼 요소
    • submit
    • focus
  • 키보드
    • keydown / keyup
  • 문서
    • DOMContentLoaded - HTML 전부 로드 시 발생
  • CSS
    • transitionend - CSS 애니메이션 종료 시 발생

버블링과 캡처링

버블링

  • 자식요소에서 부모요소로 전파

캡처링

  • 부모요소에서 자식요소로 전파

선택 방법

  • addEventListener 메소드의 세번째 이니자로 true(캡처링) 또는 false(버블링)를 전달
    • 기본값은 false(버블링)

막는 방법

  • event.stopPropagation 메소드를 호출

이벤트 위임

  • 하위요소마다 이벤트리스너를 등록하지 않고 상위요소에서 하위요소의 이벤트를 제어하는 방식

장점

  • 상위요소 한번만 등록하면 되기 때문에 메모리와 성능을 절약
  • 상위요소에서 버블링된 이벤트를 감지하기 때문에 동적으로 추가되거나 삭제되는 하위요소에도 이벤트가 적용
# html
<ul id = "menu">
    <li data-action = "save">Save</li>
    <li data-action = "load">Load</li>
    <li data-action = "search">Search</li>
</ul>
# JavaScript
let menu = document.getElementById("menu");

menu.addEventListener("click", function (event) {
    let target = event.target;
    let action = target.dataset.action;
    if (action) {
        switch (action) {
            case 'save':
                저장 로직
            break;
            case 'load':
                불러오기 로직
            break;
            case 'search':
                검색 로직
            break;
        }
    }
});
profile
열심히

0개의 댓글