๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ“‹Technical interview(Front)

[JS]์ด๋ฒคํŠธ ๋ฒ„๋ธ”๋ง๊ณผ ์บก์ฒ˜๋ง(Bubbling & Capturing)

by ๋…น์ฐจ๋ง›๊ฐœ๊ตฌ๋ฆฌ 2022. 11. 27.
๐Ÿ‘‰๐ŸปJavaScript์—๋Š” click , keypress , focus , submit , scroll , change ์™€ ๊ฐ™์€ ๋‹ค์–‘ํ•œ ์ด๋ฒคํŠธ๋“ค์ด ์žˆ๋‹ค.
๋งŒ์•ฝ ๋ถ€๋ชจ ์š”์†Œ์™€ ์ž์‹ ์š”์†Œ์— ๋‘˜ ๋‹ค ๊ฐ™์€ ์ข…๋ฅ˜์˜ ์ด๋ฒคํŠธ๊ฐ€ ํ• ๋‹น ๋˜์–ด์žˆ์„ ๋•Œ, ์ด๋ฒคํŠธ๋ฅผ ๋™์ž‘์‹œํ‚ค๋ฉด ์–ด๋–ค ์ด๋ฒคํŠธ๊ฐ€ ๋จผ์ € ์‹คํ–‰๋ ๊นŒ?

์ด๋ฒคํŠธ ๋ฒ„๋ธ”๋ง ( Event Bubbling )

์ด๋ฒคํŠธ ๋ฒ„๋ธ”๋ง์€ ํŠน์ • ํ™”๋ฉด ์š”์†Œ์—์„œ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ํ•ด๋‹น ์ด๋ฒคํŠธ๊ฐ€ ๋” ์ƒ์œ„์˜ ํ™”๋ฉด ์š”์†Œ๋“ค๋กœ ์ „๋‹ฌ๋˜์–ด ๊ฐ€๋Š” ํŠน์„ฑ์„ ์˜๋ฏธํ•œ๋‹ค.

[์˜ˆ์‹œ ๊ทธ๋ฆผ] ์‚ฌ์šฉ์ž์˜ ํ–‰๋™์œผ๋กœ pํƒœ๊ทธ์—์„œ ๋ฐœ์ƒํ•œ ์ด๋ฒคํŠธ ๋ฒ„๋ธ”๋ง ๋„์‹ํ™”

 

์œ„์™€ ๊ฐ™์ด ๋ธŒ๋ผ์šฐ์ €๋Š” ํŠน์ • ํ™”๋ฉด ์š”์†Œ์—์„œ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ๊ทธ ์ด๋ฒคํŠธ๋ฅผ ์ตœ์ƒ์œ„์— ์žˆ๋Š” ํ™”๋ฉด ์š”์†Œ๊นŒ์ง€

์ด๋ฒคํŠธ๋ฅผ ์ „ํŒŒ์‹œํ‚ค๋Š” ํŠน์„ฑ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค. 

 

์ด์™€ ๊ฐ™์€ ํ•˜์œ„์—์„œ ์ƒ์œ„ ์š”์†Œ๋กœ์˜ ์ด๋ฒคํŠธ ์ „ํŒŒ ๋ฐฉ์‹์„ ์ด๋ฒคํŠธ ๋ฒ„๋ธ”๋ง(Event Bubbling)์ด๋ผ๊ณ  ํ•œ๋‹ค.

 

๐Ÿ’ซ์˜ˆ์‹œ

3๊ฐœ์˜ ์š”์†Œ๊ฐ€ div > div > p ํ˜•ํƒœ๋กœ ์ค‘์ฒฉ๋œ ๊ตฌ์กฐ์ด๋‹ค . ์š”์†Œ ๊ฐ๊ฐ์— onClick ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ํ• ๋‹น๋˜์–ด ์žˆ์œผ๋ฉฐ

์ด๋ฒคํŠธ ๋ฐœ์ƒ์‹œ alert, ์ฆ‰ ๋ธŒ๋ผ์šฐ์ €์— ์•Œ๋ฆผ ์ฐฝ์„ ๋„์šฐ๋Š” ์ƒํƒœ๋ฅผ ๊ฐ€์ง„๋‹ค.

<div onclick="alert('div outter')">div outter
  <div onclick="alert('div inner')">div inner
    <p onclick="alert('p')">P
    </p>
  </div>
</form>

๐Ÿงฉ #1  ๊ฐ€์žฅ ์•ˆ์ชฝ p ํƒœ๊ทธ๋ฅผ ํด๋ฆญํ–ˆ์„๋•Œ ์ด๋ฒคํŠธ ๋ฒ„๋ธ”๋ง์— ์˜ํ•ด ์œ„์˜ ์ตœ์ƒ์œ„ ์ด๋ฒคํŠธ๊นŒ์ง€ ์ˆœ์„œ๋Œ€๋กœ ๋ชจ๋“  ํƒœ๊ทธ์˜ ์ด๋ฒคํŠธ๊ฐ€

๋ฐœ์ƒํ•˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค ( ์•Œ๋ฆผ ์ฐฝ์ด 3๋ฒˆ ๋œฌ๋‹ค )

๐Ÿงฉ #2  ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ค‘๊ฐ„์˜ div๋ฅผ[ div inner ] ํด๋ฆญํ–ˆ์„๋•Œ ๋ฒ„๋ธ”๋ง ํšจ๊ณผ์— ์˜ํ•ด ๋ณธ์ธ๊ณผ ๋ณธ์ธ ์ƒ์œ„์˜ ์ด๋ฒคํŠธ ๋ฐœ์ƒ์œผ๋กœ

๋‘๋ฒˆ ์•Œ๋ฆผ ์ฐฝ์ด ๋œจ๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

( p ํƒœ๊ทธ๋Š” div inner์˜ ์ž์† ํƒœ๊ทธ์ด๊ธฐ ๋•Œ๋ฌธ์— ์ƒ์œ„๋กœ ํ–ฅํ•˜๋Š” ๋ฒ„๋ธ”๋ง ํšจ๊ณผ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์€ ๋‹น์—ฐ )

๋งˆ์ง€๋ง‰ div outter ๊ฐ€์žฅ ๋งŒ๋“ค์–ด๋†“์€ ํƒœ๊ทธ์˜ ์ƒ์œ„ ์ด๊ธฐ๋•Œ๋ฌธ์— ๋ณธ์ธ์˜ ์•Œ๋ฆผ๋งŒ ๋œจ๋Š” ๋ชจ์Šต ( ๋ฌผ๋ก  body ํƒœ๊ทธ๊ฐ€ ๊ฐ€์žฅ ์ƒ์œ„ )

 

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

 


๋ฒ„๋ธ”๋ง ์ค‘๋‹จํ•˜๊ธฐ

์ด๋ฒคํŠธ ๋ฒ„๋ธ”๋ง์€ ํƒ€๊นƒ ์ด๋ฒคํŠธ์—์„œ ์‹œ์ž‘ํ•ด์„œ <html> ์š”์†Œ๋ฅผ ๊ฑฐ์ณ document ๊ฐ์ฒด๋ฅผ ๋งŒ๋‚  ๋•Œ๊นŒ์ง€ ๊ฐ ๋…ธ๋“œ์—์„œ ๋ชจ๋‘ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ๋ช‡๋ช‡ ์ด๋ฒคํŠธ๋Š” window ๊ฐ์ฒด๊นŒ์ง€ ๊ฑฐ์Šฌ๋Ÿฌ ์˜ฌ๋ผ๊ฐ€๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋•Œ๋„ ๋ชจ๋“  ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฐ๋ฐ ํ•ธ๋“ค๋Ÿฌ์—๊ฒŒ ์ด๋ฒคํŠธ๋ฅผ ์™„์ „ํžˆ ์ฒ˜๋ฆฌํ•˜๊ณ  ๋‚œ ํ›„ ๋ฒ„๋ธ”๋ง์„ ์ค‘๋‹จํ•˜๋„๋ก ๋ช…๋ นํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

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

 

<div class="div first">
    div first
    <div class="div second">
      div second
      <div class="div third">
        div third
      </div>
    </div>
</div>
var items = document.querySelectorAll("div");

items.forEach(function(item) {
  item.addEventListener('click', alertItem)
});

function alertItem(e) {
  e.stopPropagation()
  alert(e.target.className)
}
๋ฒ„๋ธ”๋ง์ด ์ผ์–ด๋‚˜์ง€ ์•Š๊ณ  ํด๋ฆญํ•œ ์š”์†Œ์˜ ์ด๋ฒคํŠธ๋งŒ ์ผ์–ด๋‚˜๋Š” ๋ชจ์Šต!!

 


์ด๋ฒคํŠธ ์บก์ณ - Event Capture

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

 

์œ„ ๊ทธ๋ฆผ์ฒ˜๋Ÿผ ํŠน์ • ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ์ตœ์ƒ์œ„ ์š”์†Œ์ธ body ํƒœ๊ทธ์—์„œ ํ•ด๋‹น ํƒœ๊ทธ๋ฅผ ์ฐพ์•„ ๋‚ด๋ ค๊ฐ„๋‹ค.

<body>
	<div class="one">
		<div class="two">
			<div class="three">
			</div>
		</div>
	</div>
</body>
var divs = document.querySelectorAll('div');
divs.forEach(function(div) {
	div.addEventListener('click', logEvent, {
		capture: true // default ๊ฐ’์€ false์ž…๋‹ˆ๋‹ค.
	});
});

function logEvent(event) {
	console.log(event.currentTarget.className);
}

addEventListener() API ์—์„œ ์˜ต์…˜ ๊ฐ์ฒด์— capture:true๋ฅผ ์„ค์ •ํ•ด์ฃผ๋ฉด ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ทธ๋Ÿฌ๋ฉด ํ•ด๋‹น ์ด๋ฒคํŠธ๋ฅผ ๊ฐ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ์ด๋ฒคํŠธ ๋ฒ„๋ธ”๋ง๊ณผ ๋ฐ˜๋Œ€ ๋ฐฉํ–ฅ์œผ๋กœ ํƒ์ƒ‰ํ•œ๋‹ค.

 

๐Ÿ“š์ฐธ๊ณ &์ถœ์ฒ˜


https://joshua1988.github.io/web-development/javascript/event-propagation-delegation/

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

728x90