Javascript

Javascript에서의 이벤트 캡쳐링, 버블링 및 이벤트 위임 이해하기

trophy98 2024. 1. 28. 19:25

자바스크립트 이벤트 처리는 웹 개발의 핵심 요소중 하나입니다. 이안에서 이벤트 캡쳐링, 버블링 및 이벤트 위임에 대해 자세히 살펴보고, 이들이 왜 중요하게 되었는지 또한 어떻게 사용하는지에 대해 살펴보겠습니다.

 

DOM(Document Object Model)의 이해

우리가 먼저 이벤트 캡쳐링, 버블링 및 이벤트 위임을 알아가기 전 DOM을 먼저 알고 가야 이해하기 쉽습니다.

DOM은 웹 페이지에 나타나는 HTML 문서 전체를 객체로 표현한 것이며, 접근 가능한 트리 구조로 표현됩니다. 웹 페이지의 모든 요소(HTML 태그)는 DOM 트리의 노드로 표현됩니다. 이 노드들 사이의 관계가 이벤트의 흐름을 결정합니다.

또한 document 객체가 웹 문서의 최상단 객체로 진입점 역할을 하고있습니다.

기본적인 이벤트 처리

  • 해당 이벤트라는 것은 웹 페이지에서 발생하는 특성 상호 작용(예: 클릭, 마우스 이동, 키보드 입력 등)을 말합니다.
  • 자바스크립트를 사용하여 이러한 이벤트에 반응하고 상호작용할 수 있습니다. 이를 위해 이벤트리스너를 DOM 요소에 추가합니다.

이벤트 캡쳐링(Event Capturing)

웹 개발 초기에는, 이벤트 처리 모델은 정말 단순했습니다. 그러나 웹 애플리케이션의 복잡성이 증가하면서, 특정 요소에서 발생한 이벤트를 상위 또는 하위 요소에서도 감지할 필요성이 생겼습니다.

이벤트 캡쳐링은 이벤트가 발생한 요소로 가기 전에 최상위 요소(window 같은 요소)에서 시작하여 해당 요소로 내려가는 과정입니다. 이는 복잡한 요소 구조에서 특정 이벤트를 상위 수준에서 먼저 처리할 수 있게 해줍니다.

 

즉 이벤트 캡쳐링은 이벤트가 DOM 트리의 최상위에서 시작하여, 실제 이벤트가 발생한 요소까지 내려가는 과정입니다. 이것은 DOM 이벤트 흐름의 첫 번째 단계라고 할 수 있습니다.

<body>
    <div id="myDiv" style="border: 2px solid blue; padding: 20px;">
        <button id="myButton">클릭하세요</button>
    </div>

    <script src="script.js"></script>
</body>
document.getElementById('myButton').addEventListener('click', function() {
    alert('버튼 클릭됨 (버블링)');
}, false);

document.getElementById('myDiv').addEventListener('click', function() {
    alert('div 클릭됨 (캡쳐링)');
}, true);

'myDiv' 요소의 경계를 클릭하면 'div 클릭됨' 이라는 알림이 먼저 표시됩니다. 이 후 이벤트는 DOM트리를 따라 내려가고, 버튼("myButton")위에서 멈추게 되므로 '버튼 클릭됨' 알림은 표시되지 않습니다.

 

이벤트 버블링(Event Bubbling)

이벤트 버블링은 이벤트가 발생한 요소에서 시작하여 DOM 트리를 따라 상위 요소로 전파되는 과정입니다.

버블링은 하위 요소에서 이벤트가 발생했을 때, 그 이벤트를 상위 요소에서도 감지하고 처리할 수 있게 합니다. 이는 이벤트를 보다 유연하게 관리할 수 있게 해줍니다.

따라서 이벤트 버블링은 캡쳐링의 반대 과정이라고 생각하면 됩니다. 이벤트가 실제 발생한 요소에서 시작하여 DOM 트리를 따라 상위 요소로 전파됩니다.

<body>
    <div id="myDiv" style="border: 2px solid blue; padding: 20px;">
        <button id="myButton">클릭하세요</button>
    </div>

    <script src="script.js"></script>
</body>
document.getElementById('myButton').addEventListener('click', function() {
    alert('버튼 클릭됨 (버블링)');
}, false);

document.getElementById('myDiv').addEventListener('click', function() {
    alert('div 클릭됨 (캡쳐링)');
}, true);

버튼("myButton")을 클릭하면, 먼저 버튼 클릭됨 이라는 알림이 표시됩니다. 이 후 이벤트는 DOM 트리를 따라 상위 요소로 전파되어, div 클릭됨 이라는 알림은 표시되지 않습니다. 그 이유는 'myDiv'에 등록된 이벤트 리스너는 캡쳐링 단계에서만 활성화되기 때문입니다.

 

결론적으로 이벤트 캡쳐링과 버블링은 이벤트가 DOM 트리를 통해 전파되는 방향이 반대라는 점에서 서로 다릅니다.

이벤트 위임(Event Delegation): 효율적인 이벤트 관리

많은 자식 요소에 각각 이벤트 리스너를 추가하는 것은 비효율적일 수 있습니다. 이는 메모리 사용량을 증가시키고, 성능 문제를 일으킬수 있습니다.

이벤트 위임은 이러한 문제를 해결하기 위해 등장했습니다. 하나의 부모 요소에 이벤트 리스너를 추가하고, 이벤트가 발생했을 때 발생한 요소의 타입이나 클래스를 확인함으로써 필요한 동작을 결정합니다.

<body>
    <ul id="myList">
        <li>항목 1</li>
        <li>항목 2</li>
        <li>항목 3</li>
    </ul>

    <script src="script.js"></script>
</body>
document.getElementById('myList').addEventListener('click', function(event) {
    if (event.target.tagName === 'LI') {
        alert(event.target.textContent + '가 클릭됨!');
    }
});
  1. 이 코드에서는 ul 요소에 이벤트 리스너를 추가하였습니다. 이 리스너는 ul 의 모든 자식 요소에 대한 클릭 이벤트를 처리합니다.
  2. 클릭 이벤트가 발생하면, 이벤트 타겟이 'li' 요소인지 확인합니다. 이는 event.target.tagName 을 검사함으로써 이루어집니다.
  3. 만약 클릭된 요소가 'li' 라면 해당 요소의 텍스트 내용과 함께 알림이 표시됩니다.

이벤트 위임의 장점은 'li' 요소가 동적으로 추가되거나 제거되더라도 별도의 이벤트 리스너를 추가하거나 제거할 필요가 없다는 것입니다. ul 요소의 이벤트 리스너가 모든 'li' 요소에 대한 클릭 이벤트를 처리하기 때문에, 효율적으로 작동합니다. 이러한 방식은 어느정도 규모가 있는 리스트나 테이블 또는 사용자 인터랙션이 많은 웹 애플리케이션에 유용합니다.

 

마무리

  • 이벤트 캡쳐링 : 이벤트가 발생한 요소로 내려가는 과정을 통해 상위 수준에서 이벤트를 관리할 수 있다.
  • 이벤트 버블링 : 하위 요소에서 발생한 이벤트를 상위 요소에서 감지하고 처리할 수 있는 방법을 제공한다.
  • 이벤트 위임 : 하나의 부모 요소에 이벤트 리스너를 설정하면서 여러 자식 요소들의 이벤트를 처리한다. 동적인 웹 애플리케이션에서 이벤트 리스너를 효율적으로 관리할 수 있게 해준다.

[참고 문서] https://medium.com/hcleedev/web-%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EB%B2%84%EB%B8%94%EB%A7%81%EA%B3%BC-%EC%BA%A1%EC%B2%98%EB%A7%81-%EC%9C%84%EC%9E%84-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0-f85d9c728561