front-end/javascript

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

MOOB 2019. 8. 22. 22:51

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

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들에 해당할 것이다.