Event delegation - accidentlywoo/legacyVue GitHub Wiki

Event delegation

  • ๋“ค์–ด๊ฐ€๊ธฐ ์ „์— list(์–ด๋–ค ๋ชฉ๋ก)๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ์ธ UI์— ๊ฐ๊ฐ ๋น„์Šทํ•œ ์ด๋ฒคํŠธ๋ฅผ ๊ฑธ์–ด์„œ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•œ๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ• ๊นŒ์š”? for๋ฌธ์œผ๋กœ addEventListener๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ• ๊นŒ์š”?

ํ•™์Šต ๋ชฉํ‘œ

  1. Event delegation์„ ์ดํ•ดํ•˜๊ณ , ํšจ์œจ์ ์ธ ์ด๋ฒคํŠธ ๋“ฑ๋ก์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

ํ•ต์‹ฌ ๊ฐœ๋…

  • Event delegation
  • Bubbling
  • Capturing

ํ•™์Šตํ•˜๊ธฐ

์ด๋Ÿฐ ์ƒํ™ฉ์—์„œ์˜ ์ด๋ฒคํŠธ ๋“ฑ๋ก

์•„๋ž˜ ํ™”๋ฉด์€ ๊ฐ€๋กœ๋กœ ๋ฐฐ์น˜๋œ ์ฑ… ๋ฆฌ์ŠคํŠธ์ž…๋‹ˆ๋‹ค. ๊ฐ๊ฐ ๋ฆฌ์ŠคํŠธ์— ํด๋ฆญ์„ ํ•  ๋•Œ ์–ด๋–ค ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•ด์•ผ ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค. addEventListener๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์ด๋ฒคํŠธ ๋“ฑ๋ก์„ ํ•  ์ˆ˜ ์žˆ์„๊ฒ๋‹ˆ๋‹ค. 4๊ฐœ์˜ ์˜ˆ์ œ์—๋Š” li ํƒœ๊ทธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. `

` li ๊ฐ๊ฐ์— addEventListener๋ฅผ ํ†ตํ•ด ์ด๋ฒคํŠธ๋ฅผ ๋“ฑ๋กํ•ฉ๋‹ˆ๋‹ค. ์ด ์ฝ”๋“œ๋Š” ์ž˜ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. `var log = document.querySelector(".log"); var lists = document.querySelectorAll("ul > li");

for(var i=0,len=lists.length; i < len; i++) { lists[i].addEventListener("click", function(evt) { log.innerHTML = "clicked" + evt.currentTarget.firstChild.src; }); }๋ธŒ๋ผ์šฐ์ €๋Š” 4๊ฐœ์˜ ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ๋ฅผ ๊ธฐ์–ตํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ list๊ฐ€ ํ›จ์”ฌ ๋” ๋งŽ๋‹ค๋ฉด ๋ธŒ๋ผ์šฐ์ €๋Š” ๊ธฐ์–ตํ•ด์•ผ ํ•  ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ๋„ ๊ทธ๋งŒํผ ๋งŽ์•„์ง‘๋‹ˆ๋‹ค. ๋น„ํšจ์œจ์ ์ด์ฃ . ๋ฌธ์ œ๋Š” ํ•œ๊ฐ€์ง€ ๋” ์žˆ์Šต๋‹ˆ๋‹ค. ๋งŒ์•ฝ list๊ฐ€ ํ•˜๋‚˜๋” ๋™์ ์œผ๋กœ ์ถ”๊ฐ€๋œ๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ์š”? ๋„ค, ์ถ”๊ฐ€๋œ ์—˜๋ฆฌ๋จผํŠธ์— ์—ญ์‹œ addEventListener๋ฅผ ํ•ด์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ๋„ ๊ฝค ๋ถˆํŽธํ•œ ์ผ ๊ฐ™๋„ค์š”. target ์ •๋ณด๊ฐ€ ์šฐ๋ฆฌ๋ฅผ ๋•์Šต๋‹ˆ๋‹ค. ์ž, ์ด๋ฒˆ์—๋Š” ulํƒœ๊ทธ์—๋งŒ ์ด๋ฒคํŠธ๋ฅผ ์ƒˆ๋กญ๊ฒŒ ๋“ฑ๋กํ•ฉ๋‹ˆ๋‹ค.ul.addEventListener("click",function(evt) { console.log(evt.currentTarget, evt.target); });์ด๋Ÿด ๊ฒฝ์šฐ li์•ˆ์— ์ด๋ฏธ์ง€๋ฅผ ํด๋ฆญํ•˜๋ฉด ์œ„ ๊ฒฐ๊ณผ๋Š” ๋ฌด์—‡์ผ๊นŒ์š”? ๋งŒ์•ฝ ul>li>imgํƒœ๊ทธ๋ฅผ ํด๋ฆญํ–ˆ๋‹ค๋ฉด ์–ด๋–ค ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ฌ๊นŒ์š”? ๊ทธ ์ „์— ์ด๋ฒคํŠธ๋Š” ์‹คํ–‰์€ ๋ ๊นŒ์š”? ์ •๋‹ต์€ '๋„ค'์ž…๋‹ˆ๋‹ค. li๋‚˜ img ํƒœ๊ทธ๋Š” ulํƒœ๊ทธ์— ์†ํ•˜๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ul์— ๋“ฑ๋กํ•œ ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ๋„ ์‹คํ–‰์ด ๋ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์ด๋ฒคํŠธ ๋ฒ„๋ธ”๋ง์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ํด๋ฆญํ•œ ์ง€์ ์ด ํ•˜์œ„์—˜๋ฆฌ๋จผํŠธ๋ผ๊ณ  ํ•˜์—ฌ๋„, ๊ทธ๊ฒƒ์„ ๊ฐ์‹ธ๊ณ  ์žˆ๋Š” ์ƒ์œ„ ์—˜๋ฆฌ๋จผํŠธ๊นŒ์ง€ ์˜ฌ๋ผ๊ฐ€๋ฉด์„œ ์ด๋ฒคํŠธ๋ฆฌ์Šค๋„ˆ๊ฐ€ ์žˆ๋Š”์ง€ ์ฐพ๋Š” ๊ณผ์ •์ž…๋‹ˆ๋‹ค. ๋งŒ์•ฝ img,li,ul์— ๊ฐ๊ฐ ์ด๋ฒคํŠธ๋ฅผ ๋“ฑ๋กํ–ˆ์—ˆ๋‹ค๋ฉด, 3๊ฐœ์˜ ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ๊ฐ€ ์‹คํ–‰ํ–ˆ์„ ๊ฒ๋‹ˆ๋‹ค. ์•„๋ž˜ ์ด๋ฏธ์ง€๋Š” ํ•˜์œ„์—˜๋ฆฌ๋จผํŠธ๋Š” 3๋ฒˆ๋ถ€ํ„ฐ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๊ณ  2,1์ˆœ์œผ๋กœ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. ๋น„์Šทํ•˜๊ฒŒ Capturing์ด๋ผ๋Š” ๊ฒƒ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐ˜ํƒœ๋กœ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒƒ์ธ๋ฐ์š”. ๊ธฐ๋ณธ์ ์œผ๋กœ Bubbling ์ˆœ์„œ๋กœ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ Bubblinf์„ ์ž˜ ๊ธฐ์–ตํ•ด๋‘๋Š” ๊ฒŒ ์ข‹์Šต๋‹ˆ๋‹ค. Capturing ๋‹จ๊ณ„์—์„œ ์ด๋ฒคํŠธ ๋ฐœ์ƒ์„ ์‹œํ‚ค๊ณ  ์‹ถ๋‹ค๋ฉด addEventListener ๋ฉ”์„œ๋“œ์˜ 3๋ฒˆ์งธ ์ธ์ž์— ๊ฐ’์„ true๋กœ ์ฃผ๋ฉด ๋ฉ๋‹ˆ๋‹ค. ![](https://cphinf.pstatic.net/mooc/20180207_43/1517986448399nM5Jy_PNG/3-5-3_Event_Bubbling.png) ์šฐ๋ฆฌ๋Š” img๋‚˜ li๋ฅผ ํด๋ฆญํ•ด๋„ ul์—๋„ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๊ณ , ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ ์‹คํ–‰์ด ๋œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ฒŒ ๋์Šต๋‹ˆ๋‹ค. img๋ฅผ ํด๋ฆญํ•˜๋ฉด ์•„๋ž˜ ๊ฒฐ๊ณผ๋Š” ๋ฌด์—‡์ด ๋‚˜์˜ฌ๊นŒ์š”? ul ๊ทธ๋ฆฌ๊ณ  img ํƒœ๊ทธ๊ฐ€ ๋‚˜์˜ต๋‹ˆ๋‹ค.ul.addEventListener("click",function(evt) { console.log(evt.currentTarget.tagName, evt.target.tagName); });๋„ค target ์ •๋ณด๋Š” ์‹ค์ œ ํด๋ฆญ ๋œ ํ•˜์œ„ ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ์•Œ๋ ค์ค๋‹ˆ๋‹ค! ์ด ์ ์„ ์ด์šฉํ•ด์„œ src๋ฅผ ์ถ”์ถœํ•  ์ˆ˜ ์žˆ์ง€ ์•Š์„๊นŒ์š”? ์ด์ œ addEventListener ๋ฉ”์„œ๋“œ๋ฅผ ํ•œ ๋ฒˆ๋งŒ ์“ฐ๋ฉด์„œ ์šฐ๋ฆฌ๋Š” ๋ชจ๋“  list์˜ image ์ •๋ณด๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”๊ตฌ๋‚˜ list ํƒœ๊ทธ๊ฐ€ ํ•˜๋‚˜ ๋” ์ถ”๊ฐ€๋œ๋‹ค๊ณ  ํ•˜์—ฌ๋„ ๋ฌธ์ œ์—†์ด ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.var ul = document.querySelector("ul"); ul.addEventListener("click",function(evt) { if(evt.target.tagName === "IMG") { log.innerHTML = "clicked" + evt.target.src; } });๊ทธ๋Ÿฐ๋ฐ ์ž‘์€ ๋ฌธ์ œ๊ฐ€ ํ•˜๋‚˜ ๋” ์žˆ๋Š” ๊ฑฐ ๊ฐ™๋„ค์š”. ์˜ˆ์ œ๋ฅผ ๋ณด๋ฉด, ์ด๋ฏธ์ง€ ํƒœ๊ทธ๋Š” padding๊ฐ’์ด ์žˆ์–ด์„œ, imgํƒœ๊ทธ์™€ liํƒœ๊ทธ ์‚ฌ์ด์— ๊ณต๋ฐฑ์ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ถ€๋ถ„(๊ณต๋ฐฑ)์„ ํด๋ฆญํ•˜๋ฉด tagName์ด li๋ผ์„œ ์œ„์—์„œ ๊ตฌํ˜„ํ•œ ์กฐ๊ฑด๋ฌธ์œผ๋กœ ๋“ค์–ด๊ฐ€์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ด ๋ถ€๋ถ„(๊ณต๋ฐฑ)์„ ํด๋ฆญํ•ด๋„ ์ด๋ฏธ์ง€ url์„ ์ถœ๋ ฅํ•  ์ˆ˜ ์žˆ์œผ๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผํ• ๊นŒ์š”?var ul = document.querySelector("ul"); ul.addEventListener("click",function(evt) { debugger; if(evt.target.tagName === "IMG") { log.innerHTML = "clicked" + evt.target.src; } else if (evt.target.tagName === "LI") { log.innerHTML = "clicked" + evt.target.firstChild.src; } });`

์ƒ๊ฐํ•ด๋ณด๊ธฐ

  1. load ์ด๋ฒคํŠธ ์ดํ›„์— ์ž‘์—…ํ•˜๋Š”๊ฒŒ ์ข‹์€ ๊ฑด ์–ด๋–ค ๊ฑธ๊นŒ์š”?
โš ๏ธ **GitHub.com Fallback** โš ๏ธ