Language/JavaScript (WEB)

๐ŸŒ ํ•œ๋ˆˆ์— ์ดํ•ดํ•˜๋Š” ์ด๋ฒคํŠธ ํ๋ฆ„ ์ œ์–ด (๋ฒ„๋ธ”๋ง & ์บก์ฒ˜๋ง)

์ธํŒŒ_ 2023. 2. 10. 14:23

๋ฒ„๋ธ”๋ง-์บก์ณ๋ง

HTML ์ด๋ฒคํŠธ์˜ ํ๋ฆ„

HTML ๋ฌธ์„œ์˜ ๊ฐ ์—˜๋ฆฌ๋จผํŠธ๋“ค์€ ์•„๋ž˜์™€ ๊ฐ™์ด ํƒœ๊ทธ ์•ˆ์˜ ํƒœ๊ทธ๊ฐ€ ์œ„์น˜ํ•˜๋Š” ์‹์œผ๋กœ ๊ณ„์ธต์ ์œผ๋กœ ์ด๋ฃจ์–ด์ง์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ณ„์ธต์  ๊ตฌ์กฐ ํŠน์ง• ๋•Œ๋ฌธ์— ๋งŒ์ผ HTML ์š”์†Œ์— ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•  ๊ฒฝ์šฐ ์—ฐ์‡„์  ์ด๋ฒคํŠธ ํ๋ฆ„์ด ์ผ์–ด๋‚˜๊ฒŒ ๋œ๋‹ค.

์˜ˆ๋ฅผ๋“ค์–ด ์•„๋ž˜ 3๊ฐœ๊ฐ€ ์ค‘์ฒฉ๋œ ๋ฐ•์Šค ์˜์—ญ์—์„œ ๊ฐ€์žฅ ์ž์‹  ์—˜๋ฆฌ๋จผํŠธ์ธ p ๋ฐ•์Šค๋ฅผ ํด๋ฆญํ•˜๋ฉด onclick ์ด๋ฒคํŠธ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ p ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๊ทธ์˜ ๋ถ€๋ชจ์ธ div์™€ form ์—˜๋ฆฌ๋จผํŠธ๋„ ๋ฐœ์ƒํ•จ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

<form onclick="alert('form')">FORM
    <div onclick="alert('div')">DIV
    	<p onclick="alert('p')">P</p>
    </div>
</form>

See the Pen event bubbleing 1 by barzz12 (@inpaSkyrim) on CodePen.

์ด๋Ÿฌํ•œ ํ˜„์ƒ์„ ์ด๋ฒคํŠธ ์ „ํŒŒ(Event Propagation)๋ผ ๋ถ€๋ฅด๋ฉฐ, ์ „ํŒŒ ๋ฐฉํ–ฅ์— ๋”ฐ๋ผ ๋ฒ„๋ธ”๋ง๊ณผ ์บก์ฒ˜๋ง์œผ๋กœ ๊ตฌ๋ถ„ํ•œ๋‹ค.

  • ๋ฒ„๋ธ”๋ง(Bubbling) : ์ž์‹ ์š”์†Œ์—์„œ ๋ฐœ์ƒํ•œ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐ”๊นฅ ๋ถ€๋ชจ ์š”์†Œ๋กœ ์ „ํŒŒ (๊ธฐ๋ณธ๊ฐ’)
  • ์บก์ณ๋ง(Capturing) : ์ž์‹ ์š”์†Œ์—์„œ ๋ฐœ์ƒํ•œ ์ด๋ฒคํŠธ๊ฐ€ ๋ถ€๋ชจ ์š”์†Œ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜์—ฌ ์•ˆ์ชฝ ์ž์‹ ์š”์†Œ๊นŒ์ง€ ๋„๋‹ฌ

Bubbling-Capturing

์–ด๋–ค ์ „ํŒŒ ๋ฐฉํ–ฅ์„ ์‚ฌ์šฉํ•  ๊ฒƒ์ด๋ƒ๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์„ค์ •์„ ํ†ตํ•ด ์ œ์–ดํ• ์ˆ˜ ์žˆ์œผ๋ฉฐ ๋‘˜์„ ๋™์‹œ์—๋„ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค. 

 

์ด๋ฒคํŠธ ์ „ํŒŒ ํ๋ฆ„

ํ‘œ์ค€ DOM ์ด๋ฒคํŠธ์—์„œ ์ •์˜ํ•œ ์ด๋ฒคํŠธ ํ๋ฆ„์—” ๋‹ค์Œ 3๊ฐ€์ง€ ๋‹จ๊ณ„๊ฐ€ ์žˆ๋‹ค.

  1. ์บก์ฒ˜๋ง ๋‹จ๊ณ„ : ์ด๋ฒคํŠธ๊ฐ€ ํ•˜์œ„ ์š”์†Œ๋กœ ์ „ํŒŒ๋˜๋Š” ๋‹จ๊ณ„
  2. ํƒ€๊นƒ ๋‹จ๊ณ„ : ์ด๋ฒคํŠธ๊ฐ€ ์‹ค์ œ ํƒ€๊นƒ ์š”์†Œ์— ์ „๋‹ฌ๋˜๋Š” ๋‹จ๊ณ„
  3. ๋ฒ„๋ธ”๋ง ๋‹จ๊ณ„ : ์ด๋ฒคํŠธ๊ฐ€ ์ƒ์œ„ ์š”์†Œ๋กœ ์ „ํŒŒ๋˜๋Š” ๋‹จ๊ณ„

์•„๋ž˜ html๋ฌธ์„œ์˜ ํ…Œ์ด๋ธ” ์•ˆ์˜ <td>๋ฅผ ํด๋ฆญํ•˜๋ฉด ์–ด๋–ป๊ฒŒ ์ด๋ฒคํŠธ๊ฐ€ ํ๋ฅด๋Š”์ง€ ์•„๋ž˜ ๊ทธ๋ฆผ์„ ๋ณด๊ณ  ์ดํ•ดํ•ด ๋ณด์ž.

Bubbling-Capturing
Bubbling-Capturing

  1. โ€‹<td>๋ฅผ ํด๋ฆญํ•˜๋ฉด ์ด๋ฒคํŠธ๊ฐ€ ์ตœ์ƒ์œ„ ์กฐ์ƒ์—์„œ ์‹œ์ž‘ํ•ด ์•„๋ž˜๋กœ ์ „ํŒŒ๋œ๋‹ค (์บก์ฒ˜๋ง ๋‹จ๊ณ„)
  2. ์ด๋ฒคํŠธ๊ฐ€ ํƒ€๊นƒ ์š”์†Œ์— ๋„์ฐฉํ•ด ๋ฆฌ์Šค๋„ˆ๋ฅผ ์‹คํ–‰ํ•œ๋‹ค (ํƒ€๊นƒ ๋‹จ๊ณ„)
  3. ๊ทธ๋ฆฌ๊ณ  ๋‹ค์‹œ ์ƒ์œ„๋กœ ์ด๋ฒคํŠธ๋ฅผ ์ „ํŒŒํ•œ๋‹ค (๋ฒ„๋ธ”๋ง ๋‹จ๊ณ„)

์ด์ฒ˜๋Ÿผ ๋ธŒ๋ผ์šฐ์ €๋Š” ์‚ฌ์šฉ์ž๋กœ๋ถ€ํ„ฐ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ๊ฐ€์žฅ ์ƒ๋‹จ์˜ ์š”์†Œ๋ถ€ํ„ฐ ํ•˜์œ„์˜ ์š”์†Œ๊นŒ์ง€ ๋‚ด๋ ค์˜ค๊ณ  ๋‹ค์‹œ ๊ฑฐ์Šฌ๋Ÿฌ ์˜ฌ๋ผ๊ฐ€๋Š” ์‹์œผ๋กœ ์ด๋ฒคํŠธ๋ฅผ ์ „๋‹ฌํ•˜์—ฌ ๋ฐœ์ƒํ•˜๋„๋ก ํ•œ๋‹ค. ๋งŒ์ผ ํƒ€๊นƒ ์š”์†Œ๊นŒ์ง€ ์ด๋ฒคํŠธ๋ฅผ ์ „ํŒŒํ•˜๋Š” ๊ณผ์ •์—์„œ ๊ทธ์˜ ๋ถ€๋ชจ, ์กฐ์ƒ์—๋„ ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ๊ฐ€ ๋“ฑ๋ก๋˜์–ด ์žˆ๋‹ค๋ฉด ์‹คํ–‰๋˜๊ฒŒ ๋œ๋‹ค.


์ด๋ฒคํŠธ ์ „ํŒŒ๊ฐ€ ์žˆ๋Š” ์ด์œ 

๊ทธ๋Ÿผ ์™œ ์ด๋ ‡๊ฒŒ ๋ณต์žกํ•˜๊ฒŒ ์ด๋ฒคํŠธ๊ฐ€ ๊ตฌ์„ฑ๋˜์–ด์ ธ ์žˆ์„๊นŒ? ์ด์— ๋Œ€ํ•ด์„œ ๋Œ€ํ‘œ์ ์œผ๋กœ ๋‹ค์Œ ๋‘๊ฐ€์ง€ ์ด์œ  ์ •๋„ ๋ฝ‘์„ ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋‹ค.

 

1. ๋…ผ๋ฆฌ์ ์ธ ์ด์œ 

Bubbling-Capturing

๊ฐ€๋งŒ ์ƒ๊ฐํ•ด๋ณด๋ฉด ์ด๋ฒคํŠธ ์ „ํŒŒ๋Š” ์–ด์ฉŒ๋ฉด ๋‹น์—ฐํ•œ ํ˜„์ƒ์ผ์ง€๋„ ๋ชจ๋ฅธ๋‹ค. ์ž์‹ ์š”์†Œ๊ฐ€ ๋ถ€๋ชจ ์š”์†Œ ์˜์—ญ ์•ˆ์— ์œ„์น˜ํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ž์‹ ์š”์†Œ๋งŒ์„ ํด๋ฆญํ•˜์˜€๋‹ค ํ•˜๋”๋ผ๋„ ๋‹ค๋ฅธ ์‹œ๊ฐ์œผ๋กœ ๋ณด๋ฉด ๋ถ€๋ชจ ์š”์†Œ๋„ ํด๋ฆญํ•œ ์…ˆ์ด ๋˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

๋งŒ์ผ ์œ„์˜ ๊ทธ๋ฆผ์—์„œ ํƒ€๊ฒŸ์ธ button ์˜์—ญ์„ ํด๋ฆญํ•ด๋„ div์˜์—ญ ์•ˆ์— ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋…ผ๋ฆฌ์ ์œผ๋กœ div ์˜์—ญ์˜ ์ด๋ฒคํŠธ๋„ ๊ฐ™์ด ๋ฐœ์ƒํ•˜๋Š” ๊ฒƒ์ด ์˜ณ์„ ๊ฒƒ์ด๋‹ค.

 

2. ์„ฑ๋Šฅ์ ์ธ ์ด์œ 

๋˜ํ•œ ์ด๋Ÿฌํ•œ ํŠน์ง• ๋•Œ๋ฌธ์— ์ด๋ฒคํŠธ ๋“ฑ๋ก ์ฝ”๋“œ๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค๋Š” ์žฅ์ ๋„ ์žˆ๋‹ค.

์˜ˆ๋ฅผ๋“ค์–ด ์•„๋ž˜์™€ ๊ฐ™์ด ์—ฌ๋Ÿฌ๊ฐœ์˜ ๋ฆฌ์ŠคํŠธ๊ฐ€ ์žˆ์„๋•Œ, ๋ช‡๋ฒˆ์งธ ๋ฆฌ์ŠคํŠธ๋ฅผ ํด๋ฆญํ•˜๋“  ์ด๋ฒคํŠธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๊ณ  ์‹ถ๋‹ค๊ณ  ํ•˜์ž.

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

Bubbling-Capturing

๋งŒ์ผ ์ด๋ฒคํŠธ ์ „ํŒŒ ๊ฐœ๋…์ด ์—†๋‹ค๋ฉด, <li> ์š”์†Œ ๋งˆ๋‹ค ์ผ์ผํžˆ ์ด๋ฒคํŠธ๋ฅผ ๋“ฑ๋กํ•ด์•ผ ํ•˜๋Š” ๋…ธ๊ฐ€๋‹ค๋ฅผ ํŽผ์ณ์•ผ ํ• ์ง€๋„ ๋ชจ๋ฅธ๋‹ค. ํ•˜์ง€๋งŒ ๋ฒ„๋ธ”๋ง์˜ ํŠน์„ฑ์„ ํ†ตํ•ด ์šฐ๋ฆฌ๋Š” ๊ทธ ๋ถ€๋ชจ ์š”์†Œ์ธ <ul> ์š”์†Œ์—๋งŒ ์ด๋ฒคํŠธ๋ฅผ ๋“ฑ๋กํ•˜๋ฉด, ์–ด๋–ค ๋ช‡๋ฒˆ์งธ์˜ li ์š”์†Œ๋ฅผ ํด๋ฆญํ•˜๋“  ๋ถ€๋ชจ ์š”์†Œ๋กœ ์ด๋ฒคํŠธ๊ฐ€ ์ „ํŒŒ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์›ํ•˜๋Š” ๊ตฌํ˜„์„ ๊ฐ„๋‹จํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด๋‹ค. ์ด ๊ธฐ๋ฒ•์„ ์ด๋ฒคํŠธ ์œ„์ž„์ด๋ผ ๋ถ€๋ฅธ๋‹ค.


๋ฒ„๋ธ”๋ง & ์บก์ฒ˜๋ง ์›๋ฆฌ

 

์ด๋ฒคํŠธ ๋ฒ„๋ธ”๋ง

๋ฒ„๋ธ”๋ง์€ ํ•œ ์š”์†Œ์— ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒ๋˜๋ฉด, ๊ทธ ์š”์†Œ์˜ ๋ถ€๋ชจ ์š”์†Œ์˜ ์ด๋ฒคํŠธ๋„ ๊ฐ™์ด ๋ฐœ์ƒ๋˜๋Š” ์ด๋ฒคํŠธ ์ „ํŒŒ๋ฅผ ๋งํ•œ๋‹ค. ์ด๋ฒคํŠธ๊ฐ€ ์ œ์ผ ๊นŠ์€ ๊ณณ์— ์žˆ๋Š” ์š”์†Œ์—์„œ ์‹œ์ž‘ํ•ด ๋ถ€๋ชจ ์š”์†Œ๋ฅผ ๊ฑฐ์Šฌ๋Ÿฌ ์˜ฌ๋ผ๊ฐ€๋ฉฐ ๋ฐœ์ƒํ•˜๋Š” ๋ชจ์–‘์ด ๋งˆ์น˜ ๋ฌผ์† ๊ฑฐํ’ˆ(bubble)๊ณผ ๋‹ฎ์•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ช…๋ช… ์ง€์–ด์กŒ๋‹ค.

์ด๋ฒคํŠธ ๋ฒ„๋ธ”๋ง

 

๋ฒ„๋ธ”๋ง ๋“ฑ๋ก

๋ธŒ๋ผ์šฐ์ €์˜ ์ด๋ฒคํŠธ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ฒ„๋ธ”๋ง ๋ฐฉ์‹์œผ๋กœ ์ด๋ฒคํŠธ๊ฐ€ ์ „ํŒŒ๋œ๋‹ค. 

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ addEventListener() ํ•จ์ˆ˜๋กœ ์š”์†Œ์˜ ์ด๋ฒคํŠธ๋ฅผ ๋“ฑ๋กํ•˜๋ฉด ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ฒ„๋ธ”๋ง ์ „ํŒŒ ๋ฐฉ์‹์œผ๋กœ ์ด๋ฒคํŠธ๊ฐ€ ํ๋ฅด๊ฒŒ ๋˜์–ด, ๋งŒ์ผ ์ž์‹ ์š”์†Œ์— ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ๋ถ€๋ชจ ์š”์†Œ๋„ ๋ฒ„๋ธ”๋ง ํ†ตํ•ด ์ด๋ฒคํŠธ๊ฐ€ ์ „ํŒŒ๋˜์–ด ๋ฆฌ์Šค๋„ˆ๊ฐ€ ํ˜ธ์ถœ๋˜๊ฒŒ ๋œ๋‹ค.

event-bubbling

// ๋ฒ„๋ธ”๋ง ๋™์ž‘ (false ์ƒ๋žต ํ•ด๋„๋จ)
element.addEventListener('click', (e) => { ... }, false);
๊ฑฐ์˜ ๋ชจ๋“  ์ด๋ฒคํŠธ๋Š” ๋ฒ„๋ธ”๋ง์ด ๋œ๋‹ค๊ณ  ๋ณด๋ฉด ๋œ๋‹ค. ๋‹ค๋งŒ focus ์ด๋ฒคํŠธ์™€ ๊ฐ™์ด ๋ฒ„๋ธ”๋ง ๋˜์ง€ ์•Š๋Š” ์ด๋ฒคํŠธ๋„ ์กด์žฌํ•˜๊ธฐ๋„ ํ•œ๋‹ค.

 

๋ฒ„๋ธ”๋ง ํ๋ฆ„

์•„๋ž˜์™€ ๊ฐ™์ด ์กฐ์ƒ(ancestor), ๋ถ€๋ชจ(parent), ์ž์‹(child) ์š”์†Œ๋“ค์ด ์ค‘์ฒฉ๋˜์–ด ์žˆ๋‹ค๊ณ  ํ•˜์ž. ๊ทธ๋ฆฌ๊ณ  ์ด๋“ค ์š”์†Œ์— ๊ฐ๊ฐ ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ๋ฅผ ๋“ฑ๋กํ•˜์˜€๋‹ค.

<div id="ancestor">
    <div id="parent">
   		<div id="child"></div>
    </div>
</div>
ancestor.addEventListener("click", (e) => {
  console.log('ancestor clicked');
})

parent.addEventListener("click", (e) => {
  console.log('parent clicked');
})

child.addEventListener("click", (e) => {
  console.log('child clicked');
})

See the Pen stopPropagatoin by barzz12 (@inpaSkyrim) on CodePen.

๋ฒ„๋ธ”๋ง์€ ์•ˆ์ชฝ์—์„œ ๋ฐ”๊นฅ์ชฝ์œผ๋กœ ์ด๋ฒคํŠธ๊ฐ€ ์ „ํŒŒ ๋˜๋Š” ํ๋ฆ„์ด๋ผ๊ณ  ํ–ˆ์—ˆ๋‹ค. ๊ฐ€์žฅ ์•ˆ์ชฝ์˜ ์ž์‹ ์š”์†Œ๋ฅผ ํด๋ฆญํ•˜์ž. ๊ทธ๋Ÿฌ๋ฉด ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ ํ˜ธ์ถœ ์ˆœ์„œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ๋œ๋‹ค.

  1. child clicked
  2. parent clicked
  3. ancestor clicked

์ด๋ฒคํŠธ ๋ฒ„๋ธ”๋ง


์ด๋ฒคํŠธ ์บก์ฒ˜๋ง

์บก์ฒ˜๋ง์€ ํ•œ ์š”์†Œ์— ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒ๋˜๋ฉด, ๊ทธ ์š”์†Œ์˜ ์ž์† ์š”์†Œ์˜ ์ด๋ฒคํŠธ๋„ ๊ฐ™์ด ๋ฐœ์ƒ๋˜๋Š” ์ด๋ฒคํŠธ ์ „ํŒŒ๋ฅผ ๋งํ•œ๋‹ค. ํ•œ๋งˆ๋””๋กœ ๋ฒ„๋ธ”๋ง ๋ฐ˜๋Œ€๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ๋‹ค๋งŒ, ์‹ค๋ฌด์—์„œ ์ž์ฃผ ์“ฐ์ด์ง€๋Š” ์•Š์ง€๋งŒ ๊ฐ€๋” ์œ ์šฉํ•œ ๊ฒฝ์šฐ๊ฐ€ ์žˆ์–ด ์•Œ์•„๋ณผ ํ•„์š”๊ฐ€ ์žˆ๋‹ค.

์บก์ฒ˜๋ง

 

์บก์ฒ˜๋ง ๋“ฑ๋ก

๋ธŒ๋ผ์šฐ์ €์˜ ์ด๋ฒคํŠธ ์ „ํŒŒ ๋ฐฉ์‹์€ ๋ฒ„๋ธ”๋ง์ด ๊ธฐ๋ณธ๊ฐ’์ด๊ธฐ ๋•Œ๋ฌธ์— ์บก์ฒ˜๋ง์œผ๋กœ ์„ค์ •ํ•˜๊ธฐ ์œ„ํ•ด์„  ๋ณ„๋„์˜ ์˜ต์…˜์„ ํ•จ์ˆ˜์— ์ฃผ์–ด์•ผ ํ•œ๋‹ค. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ addEventListener() ํ•จ์ˆ˜์˜ 3๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ true ๊ฐ’์„ ์ฃผ๋ฉด ์ด ์ด๋ฒคํŠธ ํƒ€๊ฒŸ์€ ์บก์ฒ˜๋ง์„ ํ†ตํ•ด ์ด๋ฒคํŠธ๋ฅผ ์ „ํŒŒ๋ฐ›์•„ ํ˜ธ์ถœ๋˜๊ฒŒ ๋œ๋‹ค.

์บก์ฒ˜๋ง

// ์บก์ฒ˜๋ง ๋™์ž‘
element.addEventListener('click', (e) => { ... }, true);
element.addEventListener('click', (e) => { ... }, {capture: true});

์ด๋ ‡๊ฒŒ ์˜ต์…˜ ์„ค์ •์„ ํ†ตํ•ด ๋ฒ„๋ธ”๋ง or ์บก์ฒ˜๋ง ์ด๋ฒคํŠธ ์ „ํŒŒ ๋™์ž‘์œผ๋กœ ๋“ฑ๋กํ•˜๋Š” ์ด์œ ๋Š”, ๋ธŒ๋ผ์šฐ์ €๋Š” ์บก์ณ๋ง์œผ๋กœ ํƒ์ƒ‰ํ•˜๊ณ  ๋ฒ„๋ธ”๋ง์œผ๋กœ ๋Œ์•„์˜ค๋Š”๋ฐ ๊ฐ”๋‹ค๊ฐ€ ๋Œ์•„์˜ค๋Š” ๊ณผ์ •์—์„œ ์ด๋ฒคํŠธ๊ฐ€ ๋˜‘๊ฐ™์ด ๋‘๋ฒˆ ์‹คํ–‰ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

์บก์ฒ˜๋ง์€ IE8 ์ดํ•˜์—์„œ ์ง€์›๋˜์ง€ ์•Š๋Š”๋‹ค.

 

์บก์ฒ˜๋ง ํ๋ฆ„

์•„๋ž˜์™€ ๊ฐ™์ด ์กฐ์ƒ(ancestor), ๋ถ€๋ชจ(parent), ์ž์‹(child) ์š”์†Œ๋“ค์ด ์ค‘์ฒฉ๋˜์–ด ์žˆ๋‹ค๊ณ  ํ•˜์ž. ๊ทธ๋ฆฌ๊ณ  ์ด๋“ค ์š”์†Œ์— ๊ฐ๊ฐ ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ๋ฅผ ๋“ฑ๋กํ•˜์˜€๋‹ค. ์ด๋•Œ ์บก์ฒ˜๋ง ํ๋ฆ„์„ ์„ค์žฅํ•˜๊ธฐ ์œ„ํ•ด true ๊ฐ’์„ ๋ฆฌ์Šค๋„ˆ ๋งค๊ฐœ๋ณ€์ˆ˜์— ํ• ๋‹น ํ•˜์˜€๋‹ค.

<div id="ancestor">
    <div id="parent">
   		<div id="child"></div>
    </div>
</div>
// addEventListener ํ•จ์ˆ˜ 3๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜์— true ํ˜น์€ {capture: true} ์ธ์ž๋ฅผ ์ฃผ๋ฉด ๋œ๋‹ค
ancestor.addEventListener("click", (e) => {
  console.log('ancestor clicked');
}, true)

parent.addEventListener("click", (e) => {
  console.log('parent clicked');
}, true)

child.addEventListener("click", (e) => {
  console.log('child clicked');
}, true)

See the Pen stopPropagatoin1 by barzz12 (@inpaSkyrim) on CodePen.

์บก์ฒ˜๋ง์€ ๋ฐ˜๋Œ€๋กœ ๋ฐ”๊นฅ์ชฝ์—์„œ ์•ˆ์ชฝ์œผ๋กœ ์ด๋ฒคํŠธ๊ฐ€ ์ „ํŒŒ ๋˜๋Š” ํ๋ฆ„์ด๋ผ๊ณ  ํ–ˆ์—ˆ๋‹ค. ๊ฐ€์žฅ ์•ˆ์ชฝ์˜ ์ž์‹ ์š”์†Œ๋ฅผ ํด๋ฆญํ•˜์ž. ๊ทธ๋Ÿฌ๋ฉด ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ ํ˜ธ์ถœ ์ˆœ์„œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ๋œ๋‹ค.

  1. ancestor clicked
  2. parent clicked
  3. child clicked

์ด๋ฒคํŠธ ์บก์ฒ˜๋ง

 

๋ฒ„๋ธ”๋ง + ์บก์ฒ˜๋ง ๋™์‹œ ์„ค์ •ํ•˜๊ธฐ

๋‹น์—ฐํžˆ ์š”์†Œ์— ์บก์ฒ˜๋ง ๊ณผ ๋ฒ„๋ธ”๋ง ์ „ํŒŒ๋ฅผ ๋ชจ๋‘ ํ•ธ๋“ค๋งํ•˜์—ฌ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌํ•˜๋„๋ก ํ•  ์ˆ˜๋„ ์žˆ๋‹ค. ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ ํ•จ์ˆ˜๋ฅผ ๋‘๊ฐœ ์„ค์ •ํ•ด์ฃผ๋ฉด ๋˜๋Š” ์ผ์ด๋‹ค.

// ๋ฒ„๋ธ”๋ง ํ˜ธ์ถœ
child.addEventListener("click", (e) => {
  console.log('child clicked');
})

// ์บก์ฒ˜๋ง ํ˜ธ์ถœ
child.addEventListener("click", (e) => {
  console.log('child clicked');
}, true)

See the Pen event bubbleing 4 by barzz12 (@inpaSkyrim) on CodePen.

๋”ฐ๋ผ์„œ ๊ฐ€์žฅ ์•ˆ์ชฝ์˜ ์ž์‹ ์š”์†Œ๋ฅผ ํด๋ฆญํ•˜๋ฉด ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ ํ˜ธ์ถœ ์ˆœ์„œ๋Š” ๋งˆ์น˜ ์ˆœํšŒํ•˜๋Š” ํ˜•ํƒœ๊ฐ€ ๋œ๋‹ค.

  1. ancestor clicked
  2. parent clicked
  3. child clicked
  4. child clicked
  5. parent clicked
  6. ancestor clicked

์ด๋ฒคํŠธ ์ „ํŒŒ ์ œ์–ดํ•˜๊ธฐ

 

โš ๏ธ ๋ฒ„๋ธ”๋ง & ์บก์ฒ˜๋ง ๋ฌธ์ œ์ 

์ด๋ฒคํŠธ ์ „ํŒŒ ๊ฐœ๋…์€ ์ข‹๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ๋งŒ์ผ ๋ถ€๋ชจ์™€ ์ž์‹ ๋‘˜๋‹ค ์ด๋ฒคํŠธ๋ฅผ ๋“ฑ๋กํ•œ ์ƒํƒœ์—์„œ, ์ž์‹ ์š”์†Œ๋งŒ ํด๋ฆญํ–ˆ์„๋•Œ๋งŒ ์ด๋ฒคํŠธ๋ฅผ ๋ฐœ์ƒํ•˜๊ณ  ๋ถ€๋ชจ ์š”์†Œ๋Š” ์ด๋ฒคํŠธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๊ณ  ์‹ถ์ง€ ์•Š์€ ์ƒํ™ฉ์ด ์žˆ์„ ๊ฒƒ์ด๋‹ค. 

ํ•˜์ง€๋งŒ ๋ธŒ๋ผ์šฐ์ €๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์บก์ฒ˜๋ง - ๋ฒ„๋ธ”๋ง์œผ๋กœ ๋™์ž‘ ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ฒคํŠธ ๋™์ž‘ ์ž์ฒด๋ฅผ ๋ฐ”๊ฟ€์ˆœ ์—†๋‹ค. ๊ทธ๋ฆฌ๊ณ  html ๊ตฌ์กฐ๋ฅผ ๋ด๋„  ์ž์‹ ์š”์†Œ๊ฐ€ ๋ถ€๋ชจ ์š”์†Œ ์˜์—ญ ์•ˆ์— ์œ„์น˜ํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ž์‹ ์š”์†Œ๋งŒ์„ ํด๋ฆญํ•˜์˜€๋‹ค ํ•˜๋”๋ผ๋„ ๋‹ค๋ฅธ ์‹œ๊ฐ์œผ๋กœ ๋ณด๋ฉด ๋ถ€๋ชจ ์š”์†Œ๋„ ํด๋ฆญํ•œ ์…ˆ์ด ๋˜์–ด ๋…ผ๋ฆฌ์ ์œผ๋กœ ๊ตฌ์กฐ์ ์œผ๋กœ ์ด๊ฒƒ์ด ์˜ณ๋‹ค.

๋”ฐ๋ผ์„œ ๋ธŒ๋ผ์šฐ์ €์˜ ์ด๋ฒคํŠธ ๊ตฌ์กฐ๋ฅผ ๋ฐ”๊ฟ€์ˆ˜๋Š” ์—†๊ณ , ์—˜๋ฆฌ๋จผํŠธ์˜ ์ด๋ฒคํŠธ ์ „ํŒŒ๋ฅผ ๋ฐฉ์ง€ ์ฒ˜๋ฆฌ ํ•˜๋Š” ์‹์œผ๋กœ ํ•ด๊ฒฐํ•˜์—ฌ์•ผ ํ•œ๋‹ค.

์ด๋ฒคํŠธ ์ „ํŒŒ ๋ฐฉ์ง€
์ด๋ฒคํŠธ ์ „ํŒŒ๋ฅผ ์ค‘์ง€ํ•œ๋‹ค


์ด๋ฒคํŠธ ์ „ํŒŒ ๋ฐฉ์ง€ ๋ฐฉ๋ฒ•

stopPropagation

 

๐Ÿ“Œ e.stopPropagation()

stopPropagation() ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๋ฒ„๋ธ”๋ง ๋˜๋Š” ์บก์ฒ˜๋ง ์„ค์ •์— ๋”ฐ๋ผ ์ƒ์œ„, ํ•˜์œ„๋กœ ๊ฐ€๋Š” ์ด๋ฒคํŠธ ์ „ํŒŒ๋ฅผ ๋ง‰์„ ์ˆ˜ ์žˆ๋‹ค.

ancestor.addEventListener("click", (e) => {
  e.stopPropagation() // ์ด๋ฒคํŠธ ์ „ํŒŒ ๋ฐฉ์ง€
  print('ancestor')
})

parent.addEventListener("click", (e) => {
  e.stopPropagation() // ์ด๋ฒคํŠธ ์ „ํŒŒ ๋ฐฉ์ง€
  print('parent')
})

child.addEventListener("click", (e) => {
  e.stopPropagation() // ์ด๋ฒคํŠธ ์ „ํŒŒ ๋ฐฉ์ง€
  print('child')
})

See the Pen event bubbleing 5 by barzz12 (@inpaSkyrim) on CodePen.

๊ฐ๊ฐ ์š”์†Œ๋ฅผ ํด๋ฆญํ•ด๋ณด๋ฉด ๊ฐ ์—˜๋ฆฌ๋จผํŠธ์˜ ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ๋งŒ ๋™์ž‘๋จ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

stopPropagation

 

๐Ÿ“Œ e.stopImmediatePropagation()

stopImmediatePropagation() ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด, ์ด๋ฒคํŠธ ์ „ํŒŒ์™€ ๋”๋ถˆ์–ด ํ˜•์ œ ์ด๋ฒคํŠธ ์‹คํ–‰์„ ์ค‘์ง€ํ•œ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด ์•„๋ž˜์™€ ๊ฐ™์ด ๋™์ผํ•œ child ์š”์†Œ์˜ ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ๊ฐ€ 2๊ฐœ ๋“ฑ๋ก ๋˜์–ด ์žˆ์„๋•Œ, ์–ด๋– ํ•œ ์กฐ๊ฑด์—์„œ ํด๋ฆญ ์ด๋ฒคํŠธ๋ฅผ ๋‘๋ฒˆ ์‹คํ–‰ํ•˜์ง€ ์•Š๊ณ  ํ•œ๋ฒˆ๋งŒ ์‹คํ–‰ํ† ๋ก ํ•˜๊ธธ ์›ํ•œ๋‹ค๋ฉด ์œ ์šฉํ•˜๋‹ค.

child.addEventListener("click", (e) => {
    
    if(์กฐ๊ฑด)
    	e.stopImmediatePropagation()
        
    print('child')
})

child.addEventListener("click", (e) => {
    print('child 2')
})

์ด์ฒ˜๋Ÿผ ๋™์ผํ•œ ์š”์†Œ์˜ ํŠน์ • ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ ์ผ๋•Œ, e.stopPropagation()์€ ๋ฒ„๋ธ”๋ง์€ ๋ง‰์•„์ฃผ์ง€๋งŒ, ๋‹ค๋ฅธ ํ˜•์ œ ํ•ธ๋“ค๋Ÿฌ๋“ค์ด ๋™์ž‘ํ•˜๋Š” ๊ฑด ๋ง‰์ง€ ๋ชปํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ์š”์†Œ์— ํ• ๋‹น๋œ ๋‹ค๋ฅธ ํ•ธ๋“ค๋Ÿฌ์˜ ๋™์ž‘๋„ ๋ง‰์œผ๋ ค๋ฉด e.stopImmediatePropagation() ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ์•ผ ํ•œ๋‹ค.

 

๐Ÿ“Œ e.target ์œผ๋กœ ์กฐ๊ฑด ๊ฑธ์–ด ๋ฐฉ์ง€

๋ณต์žกํ•˜์ง€๋งŒ ์ข€๋” ์„ธ์‹ฌํ•˜๊ฒŒ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ปจํŠธ๋กคํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด, ์ง์ ‘ ์กฐ๊ฑด ๋ถ„๊ธฐ๋ฅผ ํ†ตํ•ด ์ผ์ผํžˆ ์ง€์ •ํ•ด ์ค„ ์ˆ˜ ์žˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด ์ด๋ฒคํŠธ ์ „ํŒŒ๋ฅผ ์ด์šฉํ•ด html์˜ body์—๋งŒ ์ด๋ฒคํŠธ๋ฅผ ๋“ฑ๋กํ•˜๊ณ , ์–ด๋Š ์š”์†Œ์˜ ์˜์—ญ์„ ํด๋ฆญ ํ•˜๋”๋ผ๋„ ๋ฒ„๋ธ”๋ง์„ ํ†ตํ•ด body์˜ ์ด๋ฒคํŠธ๊ฐ€ ํ˜ธ์ถœ๋˜๊ฒŒ ๋˜๋Š”๋ฐ, ์ด๋•Œ ์ฝœ๋ฐฑ ํ•จ์ˆ˜์˜ ๋งค๊ฐœ๋ณ€์ˆ˜ e (event) ๋ฅผ ์ด์šฉํ•ด ํ˜„์žฌ ํ˜ธ์ถœ๋œ ํƒ€๊ฒŸ์˜ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์™€ ๋น„๊ตํ•จ์œผ๋กœ์จ ์ œ์–ด๊ฐ€ ๊ฐ€๋Šฅํ•œ ์›๋ฆฌ์ด๋‹ค.

e.target ์€ ์‹ค์ œ ์ด๋ฒคํŠธ๊ฐ€ ๊ฑธ๋ฆฐ DOM ์—˜๋ฆฌ๋จผํŠธ ๊ฐ์ฒด์ด๊ณ , ๊ทธ ์•ˆ์˜ tagName, clasName, id ์†์„ฑ์„ ํ†ตํ•ด ํƒœ๊ทธ์˜ ์ •๋ณด๋ฅผ ๋ถ„๋ฅ˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

document.body.addEventListener('click', (e) => {

    if (e.target.id === "ancestor") {
        print('ancestor')
    }

    if (e.target.id === "parent") {
        print('parent')
    }

    if (e.target.id === "child") {
        print('child')
    }
    
});

See the Pen event bubbleing 6 by barzz12 (@inpaSkyrim) on CodePen.

 

๐Ÿ“Œ e.preventDefault()

e.preventDefault() ๋Š” ์ด๋ฒคํŠธ ์ „ํŒŒ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๊ธฐ๋ณธ ์ด๋ฒคํŠธ ๋™์ž‘ ์ž์ฒด๋ฅผ ์ทจ์†Œํ•œ๋‹ค.

์˜ˆ๋ฅผ๋“ค์–ด <a href="url"> ์˜ ๋งํฌ ๊ธฐ๋Šฅ์ด๋‚˜, <form> ํƒœ๊ทธ์˜ submit ์ด๋ฒคํŠธ๋ฅผ ์ทจ์†Œํ• ๋•Œ ์œ ์šฉํ•˜๋‹ค.

 

[JS] ๐Ÿ“š ์ด๋ฒคํŠธ ๊ธฐ๋ณธ ๋™์ž‘ ์ทจ์†Œ ํ•˜๋Š” 3๊ฐ€์ง€ ๋ฐฉ๋ฒ•

์ด๋ฒคํŠธ ๊ธฐ๋ณธ ๋™์ž‘ ์ทจ์†Œํ•˜๊ธฐ ์›น๋ธŒ๋ผ์šฐ์ €์˜ ๊ตฌ์„ฑ์š”์†Œ๋“ค์€ ๊ฐ๊ฐ ๊ธฐ๋ณธ์ ์ธ ๋™์ž‘ ๋ฐฉ๋ฒ•์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค. ํ…์ŠคํŠธ ํ•„๋“œ์— ํฌ์ปค์Šค๋ฅผ ์ค€ ์ƒํƒœ์—์„œ ํ‚ค๋ณด๋“œ๋ฅผ ์ž…๋ ฅํ•˜๋ฉด ํ…์ŠคํŠธ๊ฐ€ ์ž…๋ ฅ๋œ๋‹ค. ํผ์—์„œ submit ๋ฒ„ํŠผ

inpa.tistory.com


์ง€๊ธˆ๊นŒ์ง€ ์ด๋ฒคํŠธ ๋™์ž‘ ์ œ์–ด ํ•จ์ˆ˜์— ๋Œ€ํ•ด ์ •๋ฆฌํ•ด๋ณด์ž๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ๋œ๋‹ค.

  • e.stopPropagation() : โ€‹์ด๋ฒคํŠธ ์ „ํŒŒ ์ค‘์ง€
  • e.stopImmediatePropagation() : ์ด๋ฒคํŠธ ์ „ํŒŒ ์ค‘์ง€ + ํ˜•์ œ ์ด๋ฒคํŠธ ์‹คํ–‰ ์ค‘์ง€
  • โ€‹e.preventDefault() : ์ด๋ฒคํŠธ ์ „ํŒŒ ์ค‘์ง€ + ํ˜•์ œ ์ด๋ฒคํŠธ ์‹คํ–‰ ์ค‘์ง€ + ์ด๋ฒคํŠธ ๊ธฐ๋ณธ ๋™์ž‘ ์ค‘์ง€

์ด๋ฒคํŠธ ์ „ํŒŒ ๋ฐฉ์ง€ ์ฃผ์˜์ 

๋ฒ„๋ธ”๋ง ์ด๋ฒคํŠธ ์ „ํŒŒ๋ฅผ ๋ง‰๋Š” e.stopPropagation() ๋ฉ”์„œ๋“œ๋Š” ์ถ”ํ›„์— ๋ฌธ์ œ๊ฐ€ ๋  ์ˆ˜ ์žˆ๋Š” ์ƒํ™ฉ์„ ๋งŒ๋“ค์–ด๋‚ผ ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์„ ์œ ์˜ํ•ด์•ผ ํ•œ๋‹ค.

์˜ˆ๋ฅผ๋“ค์–ด ๋‚ด ์„œ๋น„์Šค์—์„œ ์‚ฌ๋žŒ๋“ค์ด ํŽ˜์ด์ง€์— ์–ด๋””๋ฅผ ํด๋ฆญํ–ˆ๋Š”์ง€ ๋“ฑ์˜ ํ–‰๋™ ํŒจํ„ด์„ ๋ถ„์„ํ•˜๊ธฐ ์œ„ํ•ด, window ๋‚ด์—์„œ ๋ฐœ์ƒํ•˜๋Š” ํด๋ฆญ ์ด๋ฒคํŠธ ์ „๋ถ€๋ฅผ ๊ฐ์ง€๋Š” ๋ถ„์„ ์‹œ์Šคํ…œ์„ ์‚ฌ์šฉํ• ๋•Œ, ์ด๋Ÿฐ ๋ถ„์„ ์‹œ์Šคํ…œ์˜ ์ฝ”๋“œ๋Š” ํด๋ฆญ ์ด๋ฒคํŠธ๋ฅผ ๊ฐ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ๋ณดํ†ต document.addEventListener('click') ์™€ ๊ฐ™์ด ์‚ฌ์šฉํ•˜๋Š”๋ฐ, stopPropagation๋กœ ๋ฒ„๋ธ”๋ง์„ ๋ง‰์•„๋†“์€ ์˜์—ญ์—์„  '์ฃฝ์€ ์˜์—ญ(dead zone)'์ด ๋˜์–ด๋ฆฌ๊ธฐ ๋•Œ๋ฌธ์— ๋ถ„์„์ด ์ œ๋Œ€๋กœ ๋˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ๋‹ค.

๋”ฐ๋ผ์„œ ๊ผญ ํ•„์š”ํ•œ ๊ฒฝ์šฐ๋ฅผ ์ œ์™ธํ•˜๊ณค ๋ฒ„๋ธ”๋ง์„ ๋ง‰์ง€ ์•Š๋Š” ๊ฒƒ์ด ์ข‹๋‹ค. ์•„ํ‚คํ…์ฒ˜๋ฅผ ์ž˜ ๊ณ ๋ คํ•ด ์ง„์งœ ๋ง‰์•„์•ผ ํ•˜๋Š” ์ƒํ™ฉ์—์„œ๋งŒ ๋ฒ„๋ธ”๋ง์„ ๋ง‰์•„์•ผ ํ•œ๋‹ค.

 

๋งŒ์ผ ๋ฒ„๋ธ”๋ง์„ ๋ง‰์•„์•ผ ํ•ด๊ฒฐ๋  ๊ฒƒ ๊ฐ™์€ ๋ฌธ์ œ๋ผ๋ฉด ์ปค์Šคํ…€ ์ด๋ฒคํŠธ๋ฅผ ์‚ฌ์šฉํ•ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜๋„ ์žˆ๋‹ค. ๋˜ํ•œ ๊ฐ ์š”์†Œ์˜ ํ•ธ๋“ค๋Ÿฌ์˜ event ๊ฐ์ฒด์— ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•œ๋‹ค๋ฉด, event ๊ฐ์ฒด๋Š” ๋‹ค๋ฅธ ํ•ธ๋“ค๋Ÿฌ์— ๊ณต์œ ๋˜๊ธฐ ๋•Œ๋ฌธ์—, ์œ„๋‚˜ ์•„๋ž˜์ชฝ์—์„œ ๋ฌด์Šจ ์ผ์ด ์ผ์–ด๋‚˜๋Š”์ง€๋ฅผ ๋ถ€๋ชจ ์š”์†Œ์˜ ํ•ธ๋“ค๋Ÿฌ์—๊ฒŒ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ, ์ด ๋ฐฉ๋ฒ•์œผ๋กœ๋„ ์ด๋ฒคํŠธ ์ „ํŒŒ๋ฅผ ํ†ต์ œํ•  ์ˆ˜ ์žˆ๋‹ค.

ancestor.addEventListener("click", (e) => {
  e.target.customNum = 999;
  print('ancestor');
}, true)

parent.addEventListener("click", (e) => {
  e.target.customString = "hello";
  print('parent');
}, true)

child.addEventListener("click", (e) => {
  print('child' + e.target.customNum + e.target.customString)
})

stopPropagation

์œ„๋Š” ์บก์ฒ˜๋ง ์ด๋ฒคํŠธ ์ „ํŒŒ ์ฝ”๋“œ์ธ๋ฐ, child ์˜์—ญ์„ ํด๋ฆญํ•œ๋‹ค๋ฉด ๋จผ์ € ancestor์˜ ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ๊ฐ€ ํ˜ธ์ถœ๋˜๊ณ  e.target์˜ ์ถ”๊ฐ€ ์ปค์Šคํ…€ ์†์„ฑ์œผ๋กœ customNum : 999 ๊ฐ’์„ ์ €์žฅํ•˜๊ฒŒ ๋˜๊ณ , ๊ทธ๋‹ค์Œ parent์˜ ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ์—์„œ customString : "hello" ๋ฅผ ๊ทธ๋ฆฌ๊ณ  ๋งˆ์ง€๋ง‰ child์˜ ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ์—์„œ ๊ณต์œ ๋˜๋Š” event ๊ฐ์ฒด์˜ ๋“ฑ๋กํ•œ ์ปค์Šคํ…€ ์†์„ฑ์„ ๊ฐ€์ ธ์˜ค๋Š” ์›๋ฆฌ์ด๋‹ค.


# ์ฐธ๊ณ ์ž๋ฃŒ

https://developer.salesforce.com/blogs/developer-relations/2017/08/depth-look-lightning-component-events

https://ko.javascript.info/bubbling-and-capturing

https://poiemaweb.com/js-event