JS 문법 - 이벤트 다루기

KODYwiththeK·2023년 1월 1일
0

JavaScript

목록 보기
31/32

JS 문법 - 이벤트 다루기

Class: 제로베이스
Created: December 28, 2022 7:26 AM
Type: Javascript
강의 명: 초심자도 빈틈없이 학습하는 자바스크립트

이벤트 전파란?

  • 이벤트 발생 시 다른 곳으로 전파시킨다.
  • 캡쳐링 - 이벤트 발생시 가장 위 영역부터 탐색해서 전파시키는 것.
  • 버블링 -

이벤트 버블링

bubbling은 특정 요소에서 event가 발생했을 때 상위 요소로 event가 전파되는 것

  1. 브라우저에서 event bubbling이 발생하면
  2. 최상위 요소인 document 객체에 도달할 때까지 상위로 이벤트가 전파된다.
  3. 이벤트가 전파되는 것을 확인하려면 위와 같이 태그에 handler가 필요하다.
  4. focus와 같이 bubbling이 발생하지 않는 이벤트들을 제외하고 대부분의 이벤트들은 bubbling이 발생

이벤트 캡쳐링

capturing은 특정 요소에서 event가 발생했을 때 bubbling과 반대로 하위 요소로 event가 전파되는 것을 의미한다.

  1. 브라우저에서 event capturing이 발생하면
  2. 최상위 요소인 document 객체로부터 이벤트가 발생한 target 요소에 도달할 때까지 하위로 이벤트가 전파된다.
  3. capturing을 확인하기 위해서는 addEventListener()의 capture 옵션을 true로 설정해주면 된다.

이벤트 타겟

브라우저에서 event가 발생했을 때 실제로 이벤트가 발생한 요소를 target 요소라고 한다. event.target을 이용하여 접근할 수 있다.

<form id="form">form
  <div>div
      <p>p</p>
  </div>
</form> 

<script>
  const target = document.getElementById('form')
  target.onclick = function(event) {
      console.log('event.target.tagName', event.target.tagName);
      console.log('this', this.tagName);
  };
</script>

출력 결과

event.target과 같이 확인한 this는 event.currentTarget과 동일하며 다음과 같은 차이점이 있다

  • event.target : 실제로 event가 발생한 요소.
  • this : 현재 실행중인 handler가 할당된 요소
    • 여기서는 form 안의 모든 요소에서 발생하는 이벤트를 잡아낸다.
    • 따라서 form 안에서 이벤트가 발생하면 bubbling이 발생하여 handler가 실행된다.

이벤트 전파 중단

이벤트 발생 시 다른곳으로 전파를 중단시킴

  • stopProgation
    • 이벤트 전파를 막는 함수
    • 크롬, 사파리, 파이어폭스
  • cancelBubble
    • IE8 속성 true
<div class="parent">
  <button id="btn">button</button>
</div>

<script>
  const elements = document.querySelectorAll('*');
  elements.forEach((item) => {
    item.addEventListener( 'click' , (event) => {
        event.stopPropagation();
        console.log('bubbling: ' + item.tagName);
      }, {
        capture: false
      }
    );
  });
</script>
  1. 모든 선택자를 선택해서, 변수 elements 에 담아주고
  2. forEach로 각 선택자를 순회하며, click 이라는 이벤트가 발생한 이벤트에 대해서
  3. console.log 출력
  4. event.stopPropagation( ) 메소드로 이벤트 전파를 막지 않았다면
  5. 클릭이 발생한 요소로부터 부모요소로 전파되어 console.log가 쭉 출력되었을 것.
  6. capture: true 로 설정되어 있었다면, 이벤트 캡쳐링이 일어났을 것.

이벤트 전파 중단 함수

Event.preventDefault( )

이벤트의 기본 동작을 중단

// HTML
 <a href="https://cheonmro.github.io/">블로그로 이동</a>

// Javascript
var elem = document.querySelector('a');

  elem.addEventListener('click', function (e) {
  console.log(e.cancelable); // true

  // 이벤트의 기본 동작을 중단
  e.preventDefault();
});
  1. 원래는 ‘a’태그를 클릭하면 블로그로 이동을 해야하지만,
  2. 위와 같이 e.preventDefault()를 사용하게 되면, 이벤트의 기본 동작을 중단할 수 있다.
  3. 단, Event.cancelable가 true일 경우만 가능하다.
  4. Event.cancelable는 이벤트 객체의 프로퍼티로, 요소의 기본 동작을 중단할 수 있는지에 대한 여부(true/false)를 나타낸다.

**Event.stopPropagation( )**

이벤트의 전파(버블링 / 캡처링)를 중단
어느 한 요소를 이용하여 이벤트를 처리한 후, 이벤트가 부모 요소로 이벤트가 전파되는 것을 중단하기 위해 사용되는 메소드이다.

// HTML
<div id="divBox">
  <p id="paraBox">블로그
    <a id="linkBox" href="https://cheonmro.github.io/">클릭</a>
  </p>
</div>

// Javascript
document.getElementById("divBox").addEventListener("click", clickDiv);
document.getElementById("paraBox").addEventListener("click", clickPara);
document.getElementById("linkBox").addEventListener("click", clickLink);

function clickDiv(event) {
  console.log('Event for div');
}
function clickPara(event) {
  console.log('Event for p');
}
function clickLink(event) {
  event.stopPropagation();	// 이벤트의 전파를 중단함.
  console.log('Stop Propagation!')
}
  1. 위 코드에서 paraBox 요소를 클릭하게 되면, 부모요소로 이벤트가 전파된다.
  2. 그러나, linkBox 요소를 클릭하게 되면, 이벤트는 부모요소로 전파되지 않는다.

이벤트 제어 방법

이벤트를 제어하는 이유? 과도한 이벤트 발생시 성능이 저하될 수 있기 때문.

  1. Debounce : 동일 이벤트가 반복적으로 발생할 때, 이벤트가 발생이 끝나고 설정한 시간 이후에 (이벤트 발생 후 설정 시간동안 이벤트가 발생하지 않으면) 핸들러가 실행되도록 제한하는 방법이다.
  2. Throttle : 동일 이벤트가 반복적으로 발생할 때, 이벤트의 실제 주기와는 관계없이 설정한 시간마다 핸들러가 실행되도록 제한하는 방법이다.

두 개념 모두 비슷한 용도로 사용되는데, 이벤트나 함수의 실행 빈도를 조절하여 성능상의 이점을 누리기 위한 목적으로 사용한다.

위의 설명에서 알 수 있는 점은 두 방식 모두 이벤트 발생 빈도를 조절할 수 있다는 점이다. 본인이 무엇에 중점을 두고 구현을 하느냐에 따라 둘 중 어떤 방식을 사용할 것인가를 결정할 수 있다.

디바운스 (debounce)

  • 연속하여 발생한 이벤트를 그룹화 ⇒ 연속해서 발생한 이벤트 중 마지막(또는 처음) 이벤트만 호출
<input type="text" onkeyup="debounce()">
  
<script>
  let timer;
  function debounce(event) {
    if(timer) clearTimeout(timer);
    timer = setTimeout(() => {
      console.log('debounce :: ' + timer)
    }, 200)
  }
</script>

쓰로틀 (throttle)

  • 연속해서 발생한 이벤트를 그룹화 ⇒ 연속해서 발생한 이벤트 중, 정해진 시간 동안 무조건 한번만 이벤트를 발생시킨다.
<input type="text" onkeyup="throttle()">
  
<script>
  let timer;
  function throttle(event) { 
    if(!timer) { 
      timer = setTimeout(() => {
        console.log('throttle :: ' + timer)
      }, 3000)
    }
  }
</script>
profile
일상 속 선한 영향력을 만드는 개발자를 꿈꿉니다🧑🏻‍💻

0개의 댓글

관련 채용 정보