본문 바로가기
Script/JavaScript

[JavaScript] Chapter 21. 이벤트 다루기

by song.ift 2022. 12. 19.

이벤트 전파

  • 이벤트 발생 시, 다른 곳으로 전파시킴

<div id="divArea">
    <span id="spanArea">
        <button type="button" id="btn">클릭</button>
    </span>
</div>

<script>
    const divArea = document.getElementById("divArea");
    const spanArea = document.getElementById("spanArea");
    const btn = document.getElementById("btn");
    
    // 이벤트 등록
    divArea.addEventListener("click", fnDivArea);
    spanArea.addEventListener("click", fnSpanArea);
    btn.addEventListener("click", fnBtnArea);
    
    function fnDivArea(event) {
        alert('div 영역');
    }
    function fnSpanArea(event) {
        alert('span 영역');
    }
    function fnBtnArea(event) {
        alert('btn 영역');
    }
</script>
결과 : btn -> spanArea -> divArea 순으로 alert 이벤트가 실행된다.

 

이벤트 전파 중단

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

stopPropagation

  • 이벤트 전파를 막는 함수
  • 크롬, 사파리, 파이어폭스

cancelBubble

  • 이벤트 전파를 막는 함수
  • IE8 속성 true
<div id="divArea">
    <span id="spanArea">
        <button type="button" id="btn">클릭</button>
    </span>
</div>

<script>
    const divArea = document.getElementById("divArea");
    const spanArea = document.getElementById("spanArea");
    const btn = document.getElementById("btn");
    
    // 이벤트 등록
    divArea.addEventListener("click", fnDivArea);
    spanArea.addEventListener("click", fnSpanArea);
    btn.addEventListener("click", fnBtnArea);
    
    function fnDivArea(event) {
        event.stopPropagation();
        alert('div 영역');
    }
    function fnSpanArea(event) {
        event.stopPropagation();
        alert('span 영역');
    }
    function fnBtnArea(event) {
        alert('btn 영역');
    }
</script>

preventDefault

  • 이벤트 동작 중단 함수
<div id="divArea">
    <span id="spanArea">
        <a href="http://www.naver.com" id="link" target="_blank">링크클릭</a>
    </span>
</div>

<script>
    const divArea = document.getElementById("divArea");
    const spanArea = document.getElementById("spanArea");
    const link = document.getElementById("link");
    
    // 이벤트 등록
    divArea.addEventListener("click", fnDivArea);
    spanArea.addEventListener("click", fnSpanArea);
    link.addEventListener("click", fnLinkArea);
    
    function fnDivArea(event) {
        alert('div 영역');
    }
    function fnSpanArea(event) {
        alert('span 영역');
    }
    function fnLinkArea(event) {
        alert('link 영역');
        event.preventDefault();
    }
</script>
결과 : btn -> spanArea -> divArea 순으로 alert 이벤트는 실행되지만, 네이버창으로 연결되는 이벤트는 발생하지 않는다.

 

이벤트 전파

  • 이벤트 발생 시, 다른 곳으로 전파시킴
  • 캡처링 (위 -> 아래)
  • 버블링 (아래 -> 위. default)

이벤트 캡처링

  • 이벤트 발생 시, 가장 위 영역부터 탐색 (디폴트는 원래 아래에서 위로 되어있음)
  • addEventListener에 capture를 true 설정 (default 값은 false)

const capts = document.querySelectorAll("div"); // div 전체를 대상으로

capts.forEach(function(div) { // div가 복수니 foreach를 통해 이벤트 등록
    div.addEventListener("click", fnCapture, {
        capture : true
    });
});

function fnCapture(event) {
    console.log(event.currentTarget.className);
}
결과 : 최상단에 있는 div부터 className이 출력된다.

 

이벤트 타겟

  • 이벤트 발생했을 때, 시작된 곳
  • event.target 이용하여 접근 가능
const capts = document.querySelectorAll("div");

capts.forEach(function(div) {
    div.addEventListener("click", fnCapture);
});

function fnCapture(event) {
    // target : DIV 안에 클릭한 요소
    // tagName : 발생한 이벤트 DIV
    console.log(event.target.tagName = " : " + event.currentTarget.className);
}

 

이벤트 제어 방법

  1.  Debounce
  2.  Throttle

이벤트 제어 이유

  • 과도한 이벤트 발생 시, 성능 저하 => 사용자 이용X

 

디바운스 (debounce)

  • 연속하여 발생한 이벤트를 그룹화
  • 연속하여 발생한 이벤트 중 마지막(또는 처음) 이벤트만 호출

<input type="text" onkeyup="debounce();">

<script>
  var timer;
  function debounce(event) {
    if (timer)
      clearTimerout(timer);
      
    timer = setTimeout(() => {
      console.log('Debounce : ' + timer);
    }, 100);  // 0.1초 동안 이벤트가 발생하면 출력하겠다.
  }
</script>

 

스로틀 (throttle)

  • 연속하여 발생한 이벤트를 그룹화
  • 연속하여 발생한 이벤트 중 정해진 시간동안 무조간 한 번 이벤트 발생

<input type="text" onkeyup="throttle();">

<script>
  var timer;
  function throttle(event) {
    if (!timer) {
      timer = setTimeout(() => {
        console.log('throttle : ' + timer);
      }, 5000);  // 5초 동안 이벤트가 발생하면 출력하겠다.
    }
  }
</script>

댓글