ํ”„๋กœ๊ทธ๋ž˜๋ฐ/JavaScript

[JavaScript] ์ด๋ฒคํŠธ ๋ฒ„๋ธ”๋ง๊ณผ ์บก์ณ๋ง์ด ๋ฌด์—‡์ธ์ง€ ์•Œ์•„๋ด…์‹œ๋‹ค.

์šฉ๋‡ฝ 2023. 11. 16. 19:19
๋ฐ˜์‘ํ˜•

๐Ÿ“– ๋“ค์–ด๊ฐ€๋ฉฐ

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ํ•ต์‹ฌ ๊ฐœ๋… ์ค‘ ํ•˜๋‚˜์ธ ์ด๋ฒคํŠธ ๋ฒ„๋ธ”๋ง๊ณผ ์บก์ณ๋ง์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋ฒ„๋ธ”๋ง(Bubbling)

์ด๋ฒคํŠธ ๋ฒ„๋ธ”๋ง์ด๋ž€ ๋ฌด์—‡์ผ๊นŒ์š”?


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

 

๋ฒ„๋ธ”๋ง ๊ณผ์ •

๊ฐ„๋‹จํ•œ ์•„๋ž˜ ์ฝ”๋“œ ์˜ˆ์ œ๋ฅผ ๋ณด๋ฉด ๋ฐ”๋กœ ์ดํ•ด๊ฐ€ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ฐ€์žฅ ์•ˆ์ชฝ์— ์žˆ๋Š” pํƒœ๊ทธ๋ฅผ ํด๋ฆญํ–ˆ๋Š”๋ฐ 3๊ฐœ์˜ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ๋™์ž‘ํ•˜๋Š” ๊ฒŒ ๋ณด์ด์‹œ๋‚˜์š”?

  1.  p์— ํ• ๋‹น๋œ onclick ํ•ธ๋“ค๋Ÿฌ ์‹คํ–‰
  2. ๋ฐ”๊นฅ์˜ div์— ํ• ๋‹น๋œ ํ•ธ๋“ค๋Ÿฌ ์‹คํ–‰
  3. ๊ทธ ๋ฐ”๊นฅ์˜ form์— ํ• ๋‹น๋œ ํ•ธ๋“ค๋Ÿฌ ์‹คํ–‰
  4. documnet ๊ฐ์ฒด๋ฅผ ๋งŒ๋‚  ๋•Œ๊นŒ์ง€, ๊ฐ ์š”์†Œ์— ํ• ๋‹น๋œ onclick ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.

๋งˆ์ฐฌ๊ฐ€์ง€๋กœ div๋ฅผ ํด๋ฆญํ•˜๋ฉด div -> form ์ˆœ์œผ๋กœ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ์‹คํ–‰๋˜๋Š” ๋ชจ์Šต์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด์™€ ๊ฐ™์ด ์ด๋Ÿฐ ํ๋ฆ„์„ '์ด๋ฒคํŠธ ๋ฒ„๋ธ”๋ง'์ด๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค.

์ด๋ฒคํŠธ๊ฐ€ ์ œ์ผ ๊นŠ์€ ๊ณณ์— ์žˆ๋Š” ์š”์†Œ๋ถ€ํ„ฐ ๋ถ€๋ชจ ์š”์†Œ๋ฅผ ํƒ€๊ณ  ์˜ฌ๋ผ์˜ค๋Š” ๋ชจ์Šต์ด ๋งˆ์น˜ ๊ฑฐํ’ˆ(bubble)๊ณผ ๋‹ฎ์•˜๊ธฐ ๋•Œ๋ฌธ์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

์บก์ณ๋ง(Capturing)

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

์œ„ ์ฝ”๋“œ๋Š” ์ด๋ฒคํŠธ ์บก์ณ๋ง ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค. ์ด ์ฝ”๋“œ๋„ ์—ญ์‹œ '์ „์ฒด' ํ•ธ๋“ค๋Ÿฌ์— ํ• ๋‹นํ•ด์„œ ์–ด๋–ค ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ๋™์ž‘ํ•˜๊ฒŒ ๋˜๋Š”์ง€ ๋ณด์—ฌ์ฃผ๋Š” ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค.

(์ฝ”๋“œ์ƒŒ๋“œ๋ฐ•์Šค ๋‚ด ๋ฉ”๋‰ด์˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํŒŒ์ผ์— ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ๋ฅผ ์ •์˜ํ–ˆ์Šต๋‹ˆ๋‹ค.)

for (let elem of document.querySelectorAll("*")) {
        elem.addEventListener(
          "click",
          (e) => alert(`์บก์ณ๋ง: ${elem.tagName}`),
          true
        );
        elem.addEventListener("click", (e) => alert(`๋ฒ„๋ธ”๋ง: ${elem.tagName}`));
 }

p๋ฅผ ํด๋ฆญํ•˜๋ฉด ์•„๋ž˜์˜ ์ˆœ์„œ์™€ ๊ฐ™์ด ์ด๋ฒคํŠธ๊ฐ€ ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค.

  1. html -> body -> form -> div (์บก์ณ๋ง, ์ฒซ ๋ฒˆ์งธ ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ)
  2. p (ํƒ€๊นƒ ๋‹จ๊ณ„, ์บก์ณ๋ง๊ณผ ๋ฒ„๋ธ”๋ง ๋‘˜ ๋‹ค ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ์— ์„ค์ •ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋‘ ๋ฒˆ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.)
  3. div -> form -> body -> html (๋ฒ„๋ธ”๋ง, ๋‘ ๋ฒˆ์งธ ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ)

capture ์˜ต์…˜์€ ๋‘ ๊ฐ€์ง€ ์˜ต์…˜์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ์˜ ์„ธ ๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ {capture: true} ๋˜๋Š” true (capture ์ƒ๋žต ๊ฐ€๋Šฅ)

  • false => (default ๊ฐ’) ํ•ธ๋“ค๋Ÿฌ๋Š” ๋ฒ„๋ธ”๋ง ๋‹จ๊ณ„์—์„œ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.
  • true์ด๋ฉด ํ•ธ๋“ค๋Ÿฌ๋Š” ์บก์ณ๋ง ๋‹จ๊ณ„๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.

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

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

์ด๋ฒคํŠธ ํ๋ฆ„์—” ์ด 3๊ฐ€์ง€ ๋‹จ๊ณ„๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

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

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

event.target๊ณผ event.currnetTarget

๋ถ€๋ชจ ์š”์†Œ์˜ ํ•ธ๋“ค๋Ÿฌ๋Š” ์ด๋ฒคํŠธ๊ฐ€ ์ •ํ™•ํžˆ ์–ด๋””์„œ ๋ฐœ์ƒํ–ˆ๋Š”์ง€ ๋“ฑ ์ž์„ธํ•œ ์ •๋ณด๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿผ event. target๊ณผ event.currntTarget์€ ๋ฌด์Šจ ์ฐจ์ด๊ฐ€ ์žˆ์„๊นŒ์š”?

  • event.target์€ ์‹ค์ œ๋กœ ์ด๋ฒคํŠธ๊ฐ€ ์‹œ์ž‘๋œ ์š”์†Œ์ž…๋‹ˆ๋‹ค.
  • event.currentTarget์€ 'ํ˜„์žฌ' ์š”์†Œ๋กœ, ํ˜„์žฌ ์‹คํ–‰ ์ค‘์ธ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ํ• ๋‹น๋œ ์š”์†Œ์ž…๋‹ˆ๋‹ค.

์ด๋ฒคํŠธ ์ „ํŒŒ ๋ง‰๊ธฐ

event.stopPropagation()

์ด๋ฒคํŠธ ๊ฐ์ฒด์˜ ๋ฉ”์„œ๋“œ์ธ stopPropagation()์„ ์‚ฌ์šฉํ•˜๋ฉด ์ด๋ฒคํŠธ ์ „ํŒŒ๋ฅผ ๋ง‰์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

event.stopPropagation();

๋”ฐ๋ผ์„œ, ์ด๋ฒคํŠธ ๋ฒ„๋ธ”๋ง์˜ ๊ฒฝ์šฐ ํ•ด๋‹น ํ•ธ๋“ค๋Ÿฌ์˜ ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ณ  ๋ฒ„๋ธ”๋ง์„ ์ค‘๋‹จํ•˜๋„๋ก ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

event.stopImmediatePropagation()

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

(๋ฒˆ์™ธ) React์—์„œ ์ด๋ฒคํŠธ ๋ฒ„๋ธ”๋ง?

Vanilla JavaScript์—์„œ๋Š” ๋ฒ„๋ธ”๋ง์ด ์ผ์–ด๋‚˜๋Š” ์ƒํ™ฉ์„ ์‰ฝ๊ฒŒ ๋งž์ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ, ๊ฐœ์ธ์ ์œผ๋กœ React๋กœ ๊ฐœ๋ฐœ์„ ํ•  ๋•Œ์—๋„ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ• ๋‹นํ•ด ์ฃผ๋Š”๋ฐ ์ด๋ฒคํŠธ ๋ฒ„๋ธ”๋ง์ด ์ผ์–ด๋‚˜๋Š” ์ƒํ™ฉ์„ ๋Š๋ผ์ง€ ๋ชปํ•˜์—ฌ ๋” ์•Œ์•„๋ณด์•˜์Šต๋‹ˆ๋‹ค.

SynthenticEvent

React์—์„œ ์ด๋ฒคํŠธ ๋ฒ„๋ธ”๋ง์ด ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋Š๊ปด์ง€๋Š” ์ด์œ ๋Š” React๊ฐ€ ์ž์ฒด์ ์ธ ์ด๋ฒคํŠธ ์‹œ์Šคํ…œ์„ ๊ฐ€์ง€๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์ธ๋ฐ์š”.

์ด๋ฅผ 'SynthenticEvent'๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค.

React์˜ 'SynthenticEvent's๋Š” ์›น ๋ธŒ๋ผ์šฐ์ €์˜ ๋„ค์ดํ‹ฐ๋ธŒ ์ด๋ฒคํŠธ๋ฅผ ๊ฐ์‹ธ๋Š” Wrapper๋กœ, ๋ชจ๋“  ์ด๋ฒคํŠธ๊ฐ€ ์ตœ์ƒ๋‹จ์—์„œ ๋‹จ ํ•œ ๋ฒˆ๋งŒ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค.

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

ํ•˜์ง€๋งŒ ์‹ค์ œ๋กœ ์ด๋ฒคํŠธ ๋ฒ„๋ธ”๋ง์€ ์ผ์–ด๋‚ฉ๋‹ˆ๋‹ค.

SynthenticEvent๊ฐ€ ์บก์ฒ˜๋ฅผ ํ•˜๊ณ , ์ ์ ˆํ•œ ์ปดํฌ๋„ŒํŠธ์— ๋ถ„๋ฐฐํ•˜๊ณ , ๋”ฐ๋ผ์„œ React์˜ SynthenticEvent๊ฐ€ ๋„ค์ดํ‹ฐ๋ธŒ ์ด๋ฒคํŠธ๋ฅผ ๋ชจ๋ฐฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— stopPropagaion()์„ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฒคํŠธ ๋ฒ„๋ธ”๋ง์„ ๋ง‰์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ“• ๋งˆ๋ฌด๋ฆฌ

์ด๋ฒคํŠธ ์บก์ณ๋ง๊ณผ ๋ฒ„๋ธ”๋ง์„ ํ™œ์šฉํ•˜๋ฉด ์ด๋ฒคํŠธ ํ•ธ๋“ค๋ง ํŒจํ„ด์ธ ์ด๋ฒคํŠธ ์œ„์ž„์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋ฒคํŠธ ์œ„์ž„์„ ์‚ฌ์šฉํ•˜๋ฉด ์š”์†Œ๋งˆ๋‹ค ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ผ์ผ์ด ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ• ๋‹นํ•˜์ง€ ์•Š๊ณ  ์ƒ์œ„ ์š”์†Œ์—์„œ ํ•˜์œ„ ์š”์†Œ์˜ ์ด๋ฒคํŠธ๋“ค์„ ์ œ์–ดํ•˜๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค.

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

ํ•ด๋‹น ๊ธ€์—์„œ ๋‹ค๋ฃจ์ง€๋Š” ์•Š์•˜์Šต๋‹ˆ๋‹ค.

 

์ฐธ๊ณ ๋ฌธํ—Œ:

๋ฐ˜์‘ํ˜•