LoGin
article thumbnail
반응형

 

 

이벤트 버블링(EventBubbling)은 웹 개발에서 발생하는 이벤트 처리 메커니즘 중 하나로, 특정 요소에서 발생한 이벤트가 상위 요소들로 전파되는 현상을 말합니다.

 

저는 이 현상을  이벤트 겹쳐있을 때 '클릭' 이벤트를 한번 클릭한 거로 겹쳐있는 리스너들이 작동해서 이 현상에 대해 공부하게 되었습니다.

 

이벤트 버블링의 원리

이벤트 발생은 사용자가 버튼을 클릭하는 등 특정 이벤트가 발생하면, 그 이벤트는 가장 구체적인 요소에서 시작됩니다.

이벤트의 Target이라고 생각하면 됩니다.

 

이 이벤트는 해당 요소에서 시작하여 점차 상위 요소로 전파됩니다. 이를 이벤트 버블링이라고 합니다. 이는 DOM 트리(DOM Tree)를 따라 최상위 요소까지 전파됩니다.

 

각 요소는 이벤트 핸들러가 연결되어 있는 경우, 이벤트를 처리할 수 있습니다. 이벤트가 상위 요소로 전파되는 동안 각 요소의 이벤트 핸들러가 순차적으로 실행됩니다.

 

(클릭했을 때 리스너들이 반응하는 그림)

 

이벤트 버블링이 발생하는 이유

이벤트 위임(Event Delegation)

모든 하위 요소에 개별적으로 이벤트 핸들러를 붙이는 대신, 상위 요소에 한 번만 이벤트 핸들러를 붙여서 모든 하위 요소의 이벤트를 처리할 수 있습니다.

 

예시로, 여러 개의 버튼이 있는 리스트에서 각 버튼에 클릭 이벤트를 붙이는 대신, 상위 리스트 요소에 클릭 이벤트를 붙이고, 이벤트가 발생한 타깃을 확인하여 원하는 동작을 수행할 수 있습니다.

 

잘 사용하시는 분들은 좀 더 효율적인 코드를 짤 수 있겠죠

 

 

 

 

 

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>이벤트 버블링 예제</title>
    <style>
        #parent {
            padding: 20px;
            background-color: lightblue;
        }
        #child {
            padding: 20px;
            background-color: lightgreen;
        }
        button {
            padding: 10px;
            background-color: lightcoral;
        }
    </style>
</head>
<body>
    <div id="parent">
        부모 요소
        <div id="child">
            자식 요소
            <button id="button">버튼</button>
        </div>
    </div>

    <script>
        document.getElementById('parent').addEventListener('click', function() {
            alert('부모 요소 클릭됨');
        });

        document.getElementById('child').addEventListener('click', function() {
            alert('자식 요소 클릭됨');
        });

        document.getElementById('button').addEventListener('click', function(event) {
            alert('버튼 클릭됨');
            // 이벤트 버블링을 막으려면 아래 주석을 해제하세요.
            // event.stopPropagation();
        });
    </script>
</body>
</html>

 

버튼을 클릭하면 

1. 버튼 클릭됨

2. 자식 요소 클릭됨

3. 부모 요소 클릭됨

 

 

이벤트가 버튼에서 발생하여 상위 요소들로 전파되기 때문에 이런 현상이 일어나는 거죠

 

저는 이런 현상 때문에 막기 위해 공부를 했기 때문에

 

event.stopPropagation()

을 사용해서 이벤트 버블링 현상을 막았습니다.

 

 

 

 

이 외 알면 좋을 것들

event.stopImmediatePropagation()

위 코드는 event.stopPropagation()과 유사하지만, 약간 차이가 있습니다.

이벤트 버블링을 주지할 뿐 아니라, 현재 대상에 연결된 다른 이벤트 핸들러들의 실행도 중지시킵니다.

 

<button id="button">버튼</button>

<script>
    document.getElementById('button').addEventListener('click', function() {
        alert('첫 번째 핸들러');
    });

    document.getElementById('button').addEventListener('click', function(event) {
        alert('두 번째 핸들러');
        event.stopImmediatePropagation();
    });

    document.getElementById('button').addEventListener('click', function() {
        alert('세 번째 핸들러');
    });
</script>

 

위의 코드에서 버튼을 클릭하면, "두 번째 핸들러" 알림만 뜨고 "세 번째 핸들러"는 실행되지 않습니다.

 

event.preventDefault()

기본 동작을 막는 데 사용됩니다. 예를 들어, 폼의 제출 버튼을 클릭했을 때 폼이 제출되는 기본 동작을 막고 싶을 때 사용합니다.

<form id="myForm">
    <input type="text" name="name" placeholder="이름">
    <button type="submit">제출</button>
</form>

<script>
    document.getElementById('myForm').addEventListener('submit', function(event) {
        alert('폼 제출 방지됨');
        event.preventDefault(); // 폼 제출 방지
    });
</script>

 

 

이벤트 캡처링 (Event Capturing)

이벤트 캡처링은 이벤트 버블링과 반대 방향으로 이벤트가 전파되는 방식입니다. 즉, 최상위 요소에서 시작하여 이벤트 타깃 요소까지 내려가는 방식인 거죠.

 

캡처링 단계에서 이벤트를 처리하려면 'addEventListener' 메서드의 세 번째 인자로 'true'를 전달해야 합니다.

 

<div id="parent">
    부모 요소
    <div id="child">
        자식 요소
        <button id="button">버튼</button>
    </div>
</div>

<script>
    document.getElementById('parent').addEventListener('click', function() {
        alert('부모 요소 클릭됨');
    }, true); // 캡처링 단계에서 이벤트 처리

    document.getElementById('child').addEventListener('click', function() {
        alert('자식 요소 클릭됨');
    }, true); // 캡처링 단계에서 이벤트 처리

    document.getElementById('button').addEventListener('click', function(event) {
        alert('버튼 클릭됨');
    });
</script>

 

위 코드에서 버튼을 클릭하면, "부모 요소 클릭됨" → "자식 요소 클릭됨" → "버튼 클릭됨" 순서로 알림이 뜹니다.

 

이벤트 위임 (Event Delegation)

상위 요소에 이벤트 핸들러를 붙여 하위 요소의 이벤트를 처리하는 방법이 빈다. 특히 동적으로 추가되는 요소에 대한 이벤트 처리를 간편하게 만들어줍니다.

<ul id="list">
    <li>아이템 1</li>
    <li>아이템 2</li>
    <li>아이템 3</li>
</ul>

<script>
    document.getElementById('list').addEventListener('click', function(event) {
        if (event.target.tagName === 'LI') {
            alert(event.target.textContent + ' 클릭됨');
        }
    });
</script>

 

 

728x90
반응형
profile

LoGin

@LoGinShin

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!