본문 바로가기
front-end/javascript

Javascript 이벤트 버블링, 위임 target과 currentTarget의 차이

by MOOB 2019. 8. 22.

자바스크립트 이벤트의 동작

javascript의 이벤트는 브라우저 상에서 사용자와 상호작용을 통해 제어되는 동작들을 통칭한다.

이벤트 등록

자바스크립트에서는 이벤트 리스너를 통해 사용자의 특정 동작과 그 특정 동작이 발생했을 때 발생시킬 이벤트를 함수로 표현한다.

window.onload = function () {
  alert("Hello World");
};

위 함수는 window가 load 되었을 때 다음 함수를 실행시킨다.

var div = document.querySelector('div');
div.addEventListener('click', function(){
    console.log("hi");
});

위 함수는 div가 클릭되었을 때 콘솔창에 “hi”를 입력시킨다.

이벤트 버블링 & 캡쳐링

이벤트 버블링이란 어떤 이벤트가 발생되었을 때 해당 이벤트가 발생된 요소의 부모 요소를 통하여 최상위 요소까지 이벤트가 전달되는 현상을 말한다.

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
  <style>
  div.one{
  background-color:red;
  width:100px;
  height:100px;
}

div.two{
  background-color:green;
  width:70px;
  height:70px;
}

div.three{
  background-color:blue;
  width:40px;
  height:40px;
}
  </style>
</head>
<body>
  <div class="grandparent">
        <div class="parent">
            <div class="child">
            </div>
        </div>
    </div>
  <script>
    var elements = document.querySelectorAll('div');
elements.forEach(function(i){
    i.addEventListener('click', function(event){
        console.log(event.currentTarget.className);
    });
});


  </script>
</body>
</html>

여기에서 child요소를 선택하였을 때 child => parent => grandparent 의 순서대로 이벤트가 발생하는 것을 볼 수 있다.

이벤트 캡쳐링은 이와 완전히 반대로 가장 상위 요소로부터 이벤트 객체를 찾아가는 현상을 말한다. 다음 현상을 확인하기 위해서는 addEventListener 안에 capture: true를 넣으면 된다. (default는 false이다.)

이벤트 위임

이벤트 버블링과 이벤트 캡쳐링이란 특성을 적절히 사용하면 여러개의 요소가 있을 때 각각의 요소에 이벤트를 일일히 지정할 필요 없이 부모 요소에 이벤트를 하나만 주어 코드의 재사용성을 높이고 메모리를 절약할 수 있다.

<ul id="parent-list">
    <li id="1">Item 1</li>
    <li id="2">Item 2</li>
    <li id="3">Item 3</li>
    <li id="4">Item 4</li>
    <li id="5">Item 5</li>
    <li id="6">Item 6</li>
</ul>

<script>
document.getElementById("parent-list").addEventListener("click", function(e) {
    if(e.target && e.target.nodeName == "LI") {
        console.log(e.target.id);
    }
});
</script>

위 코드의 동작을 확인하면 해당 item을 클릭했을 때 그 item의 id 값을 반환한다. 그러나 script 코드를 보면 이벤트는 각 item이 아닌 그 item들을 감싸고 있는 parent-list에 준 것을 확인할 수 있다.

이벤트 객체

이벤트 객체란 이벤트가 일어나는 요소 그 자체를 의미한다. 앞서 본 코드에서 addEventListener("click", function(e) 부분에서 e.target 이 바로 이벤트 객체를 나타낸다.

그런데 자바스크립트 이벤트 코드를 뜯어보면 어떤 사람은 event.target을 또 어떤 사람은 event.currentTarget을 사용하는 것을 볼 수 있을 것이다.

이 둘에는 차이가 있는데 event.currentTarget은 이벤트가 걸려있는 위치를 반환(this가 가리키는 것과 같다.)하고 event.target은 실제 이벤트가 발생하는 위치, 내가 클릭한 요소를 반환한다. 두 객체가 같을 수도 있지만 이벤트 위임을 통해 이벤트를 주었다면 두 개는 다른 값을 가질 것이다.

이벤트 위임에서 예시로 든 코드를 예로 들면 event.currentTargetparent-list이고 event.target은 그 아래 list들에 해당할 것이다.

댓글