40 이벤트

이재철·2022년 7월 31일
0

javaScript

목록 보기
19/19

이벤트 전파

💡 이벤트 전파 (event propagation)
DOM 트리 상에 존재하는 DOM 요소 노드에서 발생한 이벤트는 DOM 트리를 통해 전파됨

<ul id="fruits">
  <li>Apple</li>
  <li>Banana</li>
  <li>Orange</li>
</ul>

ul 요소의 두 번째 자식 요소인 li 요소를 클릭하면 클릭 이벤트가 발생함
이때, 생성된 이벤트 객체는 이벤트를 발생시킨 DOM 요소인 이벤트 타깃(event target)을 중심으로 DOM 트리를 통해 전파됨

이미지 출처 | https://poiemaweb.com/js-dom

  • 캡처링 단계 : 이벤트가 상위 요소에서 하위 요소 방향으로 전파
  • 타깃 단계 : 이벤트가 이벤트 타깃에 도달
  • 버블링 단계 : 이벤트가 하위 요소에서 상위 요소 방향으로 전파

이벤트는 이벤트를 발생시킨 이벤트 타깃은 물론 상위 DOM 요소에서도 캐치할 수 있음

💡 다음 이벤트는 버블링을 통해 전파되지 않음

  • 포커스 이벤트 : focus/blur
  • 리소스 이벤트 : load/unload/abort/error
  • 마우스 이벤트 : mouseenter/mouseleave

반드시 위 이벤트를 상위 요소에서 캐치해야 한다면 대체 이벤트 (버블링을 통해 전파)

  • 포커스 이벤트 : focusin/focusout
  • 마우스 이벤트 : mouseover/mouseout

이벤트 위임

💡 이벤트 위임 (event delegation)
여러 개의 하위 DOM 요소에 각각 이벤트 핸들러를 등록하는 대신 하나의 상위 DOM 요소에 이벤트 핸들러를 등록하는 방법

이벤트 위임을 통해 하위 DOM 요소에 발생한 이벤트를 처리할 떄 주의할 점은 상위 요소에 이벤트 핸들러를 등록하기 때문에
이벤트 타깃, 실제로 발생시킨 DOM 요소가 개발자가 기대한 DOM 요소가 아닐 수 있음

-> 이벤트에 필요한 DOM요소에 한정하여 이벤트 핸들러가 실행되도록 이벤트 타깃 검사 필수


DOM 요소의 기본 동작 조작

DOM 요소의 기본 동작 중단

  • 이벤트 객체의 preventDefault 메서드는 DOM 요소의 기본 동작을 중단시킴

이벤트 전파 방지

  • 이벤트 객체의 stopPropagation 메서드는 이벤트 전파를 중지시킴
<div class="container">
  <button class="btn1">Button1</button>
  <button class="btn2">Button2</button>
</div>
<script>
	// 이벤트 위임. 클릭된 하위 버튼 요소의 color를 변경
	documnet.querySelector('.container').onclick = ({}) => {
    	if (!target.matches('.container > button')) return;
        target.style.color = 'red;
    };
	// .btn2 요소는 이벤트를 전파하지 않으므로 상위 요소에서 이벤트를 캐치
	// 자신이 발생시킨 이벤트가 전파되는 것을 중단하여 자신에게 바인딩된 이벤트 핸들러만 실행됨
	documnet.querySelector('.btn2').onclick = ({}) => {
    	e.stopPropagation(); // 이벤트 전파 중단
        e.target.style.color = 'blue;
    };
</script>
  • 하위 DOM 요소의 이벤트를 개별적으로 처리하기 위해 이벤트 전파를 중단시킴

이벤트 핸들러 내부의 this

  • 이벤트 핸들러를 호출할 때 인수로 전달한 this는 이벤트를 바인딩한 DOM 요소를 가르킴
  <button onclick="handleClick(this)">Click me</button>
  <script>
    function handleClick(button) {
    	console.log(button); // 이벤트를 바인딩한 button 요소
    	console.log(this); // window
  	}
  </script>

이벤트 핸들러 프로퍼티 방식과 addEventListener 메서드 방식

  • 이벤트 핸들러 프로퍼티 방식과 addEventListener 메서드 방식 모두 이벤트 핸들러 내부의 this는 이벤트를 바인딩한 DOM 요소를 가르킴 -> 이벤트 핸들러 내부의 this는 이벤트 객체의 currentTarget프로퍼티와 같음
  • 화살표 함수로 정의한 이벤트 핸들러 내부의 this는 상위 스코프의 this를 가르킴
  • 화살표 함수는 함수 자체의 this 바인딩을 갖지 않음
  <button class="btn">Button</button>
  <script>
    const $btn = document.querySelector('.btn');
    $btn.onclick = e => {
      // 화살표 함수 내부의 this는 상위 스코프의 this를 가르킴
      console.log(this); // window
      console.log(e.currentTarget); // $btn
      console.log(this === e.currentTarget); // true
      // this는 window를 가르키므로 window.textContnet에 NaN(undefined + 1)을 할당
      ++this.textContent;
    };
  </script>
profile
혼신의 힘을 다하다 🤷‍♂️

0개의 댓글