DOM에서의 이벤트 버블링(Event Bubbling) 현상의 주요 특징:
정의: 이벤트 버블링은 특정 요소에서 이벤트가 발생했을 때, 그 이벤트가 상위 요소들로 전파되는 현상을 말한다.
동작 방식:
순서: 가장 구체적인(깊은) 요소에서 시작하여 덜 구체적인(얕은) 요소로 이벤트가 전파.
활용: 이벤트 위임(Event Delegation) 패턴을 구현할 때 주로 사용.
여러 자식 요소에 대한 이벤트를 부모 요소 하나에서 처리할 수 있게 해준다.
제어: event.stopPropagation() 메서드를 사용하여 이벤트 버블링을 중단시킬 수 있다.
기본 동작: 대부분의 이벤트는 기본적으로 버블링된다. 단, focus 같은 일부 이벤트는 버블링되지 않는다.
이벤트 버블링은 DOM 이벤트 처리의 핵심 개념 중 하나로, 효율적인 이벤트 핸들링을 가능하게 한다.
이벤트 버블링에 대한 자세한 설명.
이벤트 버블링은 DOM(Document Object Model) 구조에서 발생하는 이벤트 전파 방식 중 하나. 이 개념을 이해하기 위해서는 먼저 DOM 트리 구조를 이해해야 한다.
DOM 트리 구조:
HTML 문서는 트리 구조로 표현됩니다. 각 요소는 노드이며, 부모-자식 관계를 가진다.
예를 들어:
<div id="grandparent">
<div id="parent">
<button id="child">클릭</button>
</div>
</div>
이벤트 버블링 과정:
시각적 표현:
이벤트 버블링을 물속의 거품이 위로 올라가는 것처럼 생각할 수 있습니다.
이벤트 버블링 및 캡처링 이미지
코드 예제:
document.getElementById("child").addEventListener("click", function() {
console.log("버튼 클릭됨");
});
document.getElementById("parent").addEventListener("click", function() {
console.log("부모 div 클릭됨");
});
document.getElementById("grandparent").addEventListener("click", function() {
console.log("조부모 div 클릭됨");
});
버튼을 클릭하면 콘솔에 다음과 같이 출력:
버튼 클릭됨
부모 div 클릭됨
조부모 div 클릭됨
이벤트 버블링 제어:
event.stopPropagation(): 이벤트 전파를 중지.
아래는 이벤트 버블링을 제어하는 예제 코드로,event.currentTarget을 사용하는 방법. 이 예제에서는 자식 요소를 클릭할 때 부모와 조부모 요소로의 이벤트 전파를 중지하는 기능을 추가.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<title>이벤트 버블링 예제</title>
<style>
div {
padding: 20px;
margin: 10px;
}
#grandparent {
border: 3px solid red;
background-color: #ffcccb;
}
#parent {
border: 3px solid green;
background-color: #90ee90;
}
#child {
border: 3px solid blue;
background-color: #add8e6;
}
</style>
</head>
<body>
<div id="grandparent">
조부모
<div id="parent">
부모
<div id="child">자식</div>
</div>
</div>
<script>
document.getElementById("child").addEventListener("click", function (e) {
console.log("자식 클릭됨");
alert("자식 클릭됨");
// 이벤트 전파 중지
e.stopPropagation();
});
document.getElementById("parent").addEventListener("click", function (e) {
console.log("부모 클릭됨");
alert("부모 클릭됨");
});
document.getElementById("grandparent").addEventListener("click", function (e) {
console.log("조부모 클릭됨");
alert("조부모 클릭됨");
});
</script>
</body>
</html>
동작 방식:
자식 요소를 클릭하면 "자식 클릭됨"이라는 알림이 표시되고, 콘솔에 해당 메시지가 출력.
`stopPropagation()`으로 인해 부모와 조부모 요소의 클릭 이벤트는 발생하지 않으므로,
"부모 클릭됨" 및 "조부모 클릭됨" 메시지는 출력되지 않는다.
event.target vs event.currentTarget: 실제 이벤트가 발생한 요소와 현재 이벤트 핸들러가 attached된 요소를 구분할 수 있다.event.target과 event.currentTarget의 차이를 이해하는 것은 JavaScript에서 이벤트 처리를 효과적으로 사용하는 데 매우 중요하다. event.target과 event.currentTarget의 차이event.target:event.target은 해당 버튼을 가리킨다.event.currentTarget:아래는 event.target과 event.currentTarget을 사용하는 간단한 HTML 및 JavaScript 코드:
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<title>event.target vs event.currentTarget</title>
<style>
#parent {
padding: 20px;
background-color: #90ee90;
border: 2px solid green;
}
#child {
padding: 10px;
background-color: #add8e6;
border: 2px solid blue;
cursor: pointer;
}
</style>
</head>
<body>
<div id="parent">
부모 요소 (클릭하세요)
<div id="child">자식 요소 (클릭하세요)</div>
</div>
<script>
document.getElementById("parent").addEventListener("click", function(e) {
console.log("현재 이벤트 핸들러가 등록된 요소:", e.currentTarget); // 부모 요소
console.log("이벤트가 발생한 요소:", e.target); // 클릭된 요소
});
document.getElementById("child").addEventListener("click", function(e) {
console.log("자식 클릭됨");
alert("자식 클릭됨");
});
</script>
</body>
</html>
동작 방식
자식 요소(`child`)를 클릭하면:
콘솔에 "현재 이벤트 핸들러가 등록된 요소:"로 부모 요소가 출력 (`e.currentTarget`).
"이벤트가 발생한 요소:"로 자식 요소가 출력 (`e.target`).
부모 요소(`parent`)를 직접 클릭하면:
"현재 이벤트 핸들러가 등록된 요소:"로 부모 요소가 출력(`e.currentTarget`).
"이벤트가 발생한 요소:"로 부모 요소도 출력 (`e.target`).
이벤트 캡처링:
버블링의 반대 방향으로 진행되는 이벤트 전파 방식. 루트에서 시작하여 타겟 요소까지 내려간다.
실제 응용:
이벤트 버블링은 복잡해 보일 수 있지만, 이를 이해하고 활용하면 효율적인 이벤트 핸들링이 가능. 특히 대규모 애플리케이션에서 성능 최적화에 도움이 된다.
Citations:
[1] https://steady-record.tistory.com/entry/%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EB%B2%84%EB%B8%94%EB%A7%81
[2] https://jungpaeng.tistory.com/69
[3] https://samslow.github.io/development/2020/07/14/Event-handling/
[4] https://inpa.tistory.com/entry/JS-%F0%9F%93%9A-%EB%B2%84%EB%B8%94%EB%A7%81-%EC%BA%A1%EC%B3%90%EB%A7%81
[5] https://velog.io/@jakeseo_me/2-%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EC%BA%A1%EC%B2%98%EB%A7%81-%EB%B2%84%EB%B8%94%EB%A7%81
[6] https://code-masterjung.tistory.com/85
[7] https://ko.javascript.info/bubbling-and-capturing
[8] https://doqtqu.tistory.com/308
[9] https://developer.mozilla.org/ko/docs/Learn/JavaScript/Building_blocks/Event_bubbling
[10] https://joon2974.tistory.com/entry/JavaScript-%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
[11] https://shawnkim.tistory.com/86
[12] https://velog.io/@jakeseo_me/2-%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EC%BA%A1%EC%B2%98%EB%A7%81-%EB%B2%84%EB%B8%94%EB%A7%81
[13] https://velog.io/@sunohvoiin/DOM-%ED%8A%B8%EB%A6%AC%EC%99%80-%EC%84%A0%ED%83%9D-%ED%83%90%EC%83%89-DOM-Tree-Query-Traversing
[14] https://inpa.tistory.com/entry/JS-%F0%9F%93%9A-%EB%B2%84%EB%B8%94%EB%A7%81-%EC%BA%A1%EC%B3%90%EB%A7%81
[15] https://ko.javascript.info/bubbling-and-capturing
[16] https://creativevista.tistory.com/entry/Javascript%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-DOM-%EB%A7%88%EC%8A%A4%ED%84%B0%ED%95%98%EA%B8%B0-%EC%B4%88%EB%B3%B4%EC%9E%90%EB%A5%BC-%EC%9C%84%ED%95%9C-%EC%99%84%EB%B2%BD-%EA%B0%80%EC%9D%B4%EB%93%9C
[17] https://yeonhapark.github.io/blog/event-bubbling/
[18] https://zindex.tistory.com/33
[19] https://joon2974.tistory.com/entry/JavaScript-%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
[20] https://velog.io/@sangyoung23/javascript-DOM-%ED%8A%B8%EB%A6%AC%EC%99%80-DOM-%ED%83%90%EC%83%89
[21] https://ko.javascript.info/dom-nodes
[22] https://dev-chim.tistory.com/entry/Javascript-target-vs-currentTarget
[23] https://hclee2575.tistory.com/342
[24] https://velog.io/@hi6863/JS-event-target%EA%B3%BC-currentTarget%EC%9D%98-%EC%B0%A8%EC%9D%B4
[25] https://choar816.tistory.com/155
[26] https://mong-blog.tistory.com/entry/JS-eventtarget-eventcurrentTarget%EC%9D%98-%EC%B0%A8%EC%9D%B4feat-%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EB%B2%84%EB%B8%94%EB%A7%81
HTML 요소들을 시각적으로 구분하면 이벤트 버블링을 더 쉽게 이해할 수 있다. 아래에 색상과 테두리를 추가한 예제 제시.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>이벤트 버블링 예제</title>
<style>
div {
padding: 20px;
margin: 10px;
}
#grandparent {
border: 3px solid red;
background-color: #ffcccb;
}
#parent {
border: 3px solid green;
background-color: #90ee90;
}
#child {
border: 3px solid blue;
background-color: #add8e6;
}
</style>
</head>
<body>
<div id="grandparent">
조부모
<div id="parent">
부모
<div id="child">자식</div>
</div>
</div>
<script>
document.getElementById("child").addEventListener("click", function(e) {
console.log("자식 클릭됨");
alert("자식 클릭됨");
});
document.getElementById("parent").addEventListener("click", function(e) {
console.log("부모 클릭됨");
alert("부모 클릭됨");
});
document.getElementById("grandparent").addEventListener("click", function(e) {
console.log("조부모 클릭됨");
alert("조부모 클릭됨");
});
</script>
</body>
</html>
이 코드를 실행하면:
이렇게 시각적으로 구분된 요소들을 통해 이벤트 버블링의 개념을 더 쉽게 이해할 수 있다. 자식 요소를 클릭하면 그 이벤트가 어떻게 상위 요소로 전파되는지 직접 확인할 수 있다.
이벤트 버블링에 대한 이미지를 찾기 위해 제공된 검색 결과를 살펴보면, 이미지가 포함된 링크는 명시되어 있지 않습니다. 대신, 이벤트 버블링을 설명하는 내용을 포함하고 있는 여러 링크가 있습니다. 아래는 이벤트 버블링에 대한 설명과 이미지가 포함된 링크를 정리한 것입니다:
이벤트 버블링 개념:
기타 유용한 링크:
Citations:
[1] https://velog.io/@mochafreddo/%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EB%B2%84%EB%B8%94%EB%A7%81Event-Bubbling%EA%B3%BC-%EC%9D%B4%EB%A5%BC-%EC%A0%9C%EC%96%B4%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95%EC%97%90-%EB%8C%80%ED%95%9C-%EC%8B%AC%EC%B8%B5-%EC%9D%B4%ED%95%B4
[2] https://seo-tory.tistory.com/85
[3] https://joshua1988.github.io/web-development/javascript/event-propagation-delegation/
[4] https://velog.io/@jakeseo_me/2-%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EC%BA%A1%EC%B2%98%EB%A7%81-%EB%B2%84%EB%B8%94%EB%A7%81
[5] https://yoo-blog.tistory.com/m/12
[6] https://loginshin.tistory.com/97
[7] https://www.howdy-mj.me/dom/event-capturing-and-bubbling
[8] https://gobae.tistory.com/143
[9] https://inpa.tistory.com/entry/JS-%F0%9F%93%9A-%EB%B2%84%EB%B8%94%EB%A7%81-%EC%BA%A1%EC%B3%90%EB%A7%81