๐Ÿ’ป๐Ÿ’€/๊ฐœ๋ฐœ

[JS] ์ด๋ฒคํŠธ์˜ target๊ณผ currentTarget ์ฐจ์ด (with ๋ฒ„๋ธ”๋ง)

db2 2022. 8. 6. 00:09

์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ์˜ Event ๊ฐ์ฒด

JavaScript์—์„œ๋Š” addEventListener() ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด DOM ์š”์†Œ์— ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๋“ฑ๋กํ•  ์ˆ˜ ์žˆ๋‹ค. ๋“ฑ๋ก๋œ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋Š” ํ˜ธ์ถœ๋  ๋•Œ ์ž๋™์ ์œผ๋กœ Event ๊ฐ์ฒด๋ฅผ ์ฒซ ๋ฒˆ์งธ ์ธ์ž๋กœ ์ „๋‹ฌ๋ฐ›๋Š”๋‹ค. ๋ณดํ†ต ์ž„์˜๋กœ e๋‚˜ event๋กœ ์ด๋ฆ„์ง€์–ด ์‚ฌ์šฉํ•˜๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ ์—ฌ๊ธฐ์— ํ•ด๋‹น๋œ๋‹ค. ์ด ์ด๋ฒคํŠธ ๊ฐ์ฒด๋Š” ์•ž์œผ๋กœ ๋‹ค๋ฃจ๊ฒŒ ๋  target, currentTaget๊ณผ ๊ฐ™์€ ํ”„๋กœํผํ‹ฐ์™€ stopPropagation()๊ณผ ๊ฐ™์€ ๋ฉ”์„œ๋“œ ๋“ฑ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.

const input = document.querySelector('.input');

// ํŒŒ๋ผ๋ฏธํ„ฐ๋ช…์€ ๊ผญ e๊ฐ€ ์•„๋‹ˆ์–ด๋„ ๋œ๋‹ค. 
const handleChange = (e) => {
    const { name, value } = e.target;
    console.log(name, value);
}

input.addEventListener('change', handleChange);

์ด๋ฒคํŠธ ๋ฒ„๋ธ”๋ง๊ณผ ์บก์ฒ˜๋ง

๋ถ€๋ชจ ์š”์†Œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์š”์†Œ์—์„œ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•œ ๊ฒฝ์šฐ, ์บก์ฒ˜๋ง๊ณผ ๋ฒ„๋ธ”๋ง์ด ์ฐจ๋ก€๋Œ€๋กœ ์‹คํ–‰๋œ๋‹ค.

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

๊ธฐ๋ณธ์ ์œผ๋กœ ๋ชจ๋“  ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋Š” ๋ฒ„๋ธ”๋ง ๋‹จ๊ณ„์— ๋™์ž‘ํ•˜๋„๋ก ์„ค์ •๋˜์–ด ์žˆ๋‹ค. ์บก์ฒ˜๋ง ํƒ€์ž…์˜ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ๋“ฑ๋ก๋˜์–ด ์žˆ๋‹ค๋ฉด, ๋ชจ๋“  ์บก์ฒ˜๋ง ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ๋จผ์ € ํ˜ธ์ถœ๋œ ์ดํ›„ ๋ฒ„๋ธ”๋ง ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ํ˜ธ์ถœ๋  ๊ฒƒ์ด๋‹ค.

target ํ”„๋กœํผํ‹ฐ์™€ currentTarget ํ”„๋กœํผํ‹ฐ ๋น„๊ต

์ด ๋‘ ํ”„๋กœํผํ‹ฐ๋Š” ์ด๋ฒคํŠธ ๋ฒ„๋ธ”๋ง๊ณผ ์บก์ฒ˜๋ง์ด ๋ฐœ์ƒํ•˜๋Š” ์ˆœ๊ฐ„์— ์ฐจ์ด๊ฐ€ ๋ช…ํ™•ํ•ด์ง„๋‹ค.

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

๋ฒ„๋ธ”๋ง ์˜ˆ์ œ

๋ฒ„๋ธ”๋ง ๋‹จ๊ณ„์—์„œ์˜ e.target๊ณผ e.currentTarget์˜ ์ฐจ์ด๋ฅผ ํ™•์ธํ•ด๋ณด๊ธฐ ์œ„ํ•ด ์•„๋ž˜์™€ ๊ฐ™์ด ์ค‘์ฒฉ๋œ ๊ตฌ์กฐ์˜ ๋ ˆ์ด์•„์›ƒ์„ ๋งŒ๋“ค์—ˆ๋‹ค.

const outer = document.createElement("div");
const inner = document.createElement("div");
const button = document.createElement("button");

outer.id = "outer";
inner.id = "inner";
button.id = "button";

outer.innerHTML = "outer";
inner.innerHTML = "inner";
button.innerHTML = "button";

inner.appendChild(button);
outer.appendChild(inner);
app.appendChild(outer);

๊ทธ๋ฆฌ๊ณ  ๋ชจ๋“  ์š”์†Œ์˜ ํด๋ฆญ ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ์— printLog ํ•จ์ˆ˜๋ฅผ ๋“ฑ๋กํ–ˆ๋‹ค.

function printLog(e) {
  const { target, currentTarget } = e;
  console.log(`currentTarget: ${currentTarget.id}, target: ${target.id}`);
}

outer.addEventListener("click", printLog);
inner.addEventListener("click", printLog);
button.addEventListener("click", printLog);

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

012
์ˆœ์„œ๋Œ€๋กœ button์„ ํด๋ฆญํ–ˆ์„ ๋•Œ, inner๋ฅผ ํด๋ฆญํ–ˆ์„ ๋•Œ, outer๋ฅผ ํด๋ฆญํ–ˆ์„ ๋•Œ์˜ ๊ฒฐ๊ณผ

์ฟจํ•˜๊ฒŒ ๋ฒ„๋ธ”๋ง ์ฒ˜๋ฆฌํ•˜๊ธฐ

stopPropgation()๋‚˜ stopImmediatePropagation() ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ด๋ฒคํŠธ ์ „ํŒŒ๋ฅผ ๋ง‰์„ ์ˆ˜ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด ๋ฐฉ๋ฒ•์€ ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ๋ฒ„๊ทธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๊ธฐ์— ๋”ฑ ์ข‹๋‹ค. ๋‹ค๋ฅธ ๊ฐœ๋ฐœ์ž๊ฐ€ ๋ถ€๋ชจ ์š”์†Œ์— ์ •๋ง ํ•„์š”ํ•œ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๋“ฑ๋กํ•ด๋†จ๋Š”๋ฐ ๋‚ด๊ฐ€ ๋ฏธ์ฒ˜ ๊ทธ๊ฑธ ์ธ์ง€ํ•˜์ง€ ๋ชปํ•˜๊ณ  ๋ฒ„๋ธ”๋ง์„ ๋ง‰์•„๋ฒ„๋ฆฐ๋‹ค๋ฉด? ๊ทธ ์ˆœ๊ฐ„ ๊ณ ๋‚œ๊ณผ ์—ญ๊ฒฝ์˜ ์‹œ์ž‘์ด๋‹ค.

๋”ฐ๋ผ์„œ ์œ„์˜ ๋ฐฉ๋ฒ•๋ณด๋‹ค๋Š” target๊ณผ currentTarget์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ถ”์ฒœํ•œ๋‹ค.

function printLog(e) {
  const { target, currentTarget } = e;
  // ํด๋ฆญ๋œ ๋Œ€์ƒ์ด ์ž๊ธฐ ์ž์‹ ์ผ ๋•Œ๋งŒ ๋กœ์ง์ด ๋™์ž‘ํ•˜๋„๋ก ์ฒ˜๋ฆฌํ•œ๋‹ค. 
  if (target !== currentTarget) {
    return;
  }
  console.log(`currentTarget: ${currentTarget.id}, target: ${target.id}`);
}

๊ทธ๋Ÿฌ๋ฉด ์ด๋ ‡๊ฒŒ ๋”์ด์ƒ ๋ฒ„๋ธ”๋ง ๋˜์ง€ ์•Š๊ณ , ํด๋ฆญํ•œ ์š”์†Œ์— ๋“ฑ๋ก๋œ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ํ•˜๋‚˜๋งŒ ํ˜ธ์ถœ์ด ๋˜์–ด ์‹คํ–‰๋œ๋‹ค.

์œ„์—์„œ๋ถ€ํ„ฐ ์ˆœ์„œ๋Œ€๋กœ button์„ ํด๋ฆญํ–ˆ์„ ๋•Œ, inner๋ฅผ ํด๋ฆญํ–ˆ์„ ๋•Œ, outer๋ฅผ ํด๋ฆญํ–ˆ์„ ๋•Œ์˜ ๊ฒฐ๊ณผ

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

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

์•„์ดํ…œ์„ ํด๋ฆญํ•˜์—ฌ ์ทจ์†Œ์„ ์„ ํ† ๊ธ€ํ•˜๋Š” ์˜ˆ์ œ์ด๋‹ค.

const ul = document.createElement("ul");
const li1 = document.createElement("li");
const li2 = document.createElement("li");
const li3 = document.createElement("li");

li1.innerHTML = "item 1";
li2.innerHTML = "item 2";
li3.innerHTML = "item 3";

ul.appendChild(li1);
ul.appendChild(li2);
ul.appendChild(li3);
app.appendChild(ul);

์ถ”์ฒœํ•˜์ง€ ์•Š๋Š” ๋ฐฉ๋ฒ•์€ ์ด๋ ‡๊ฒŒ ๋˜‘๊ฐ™์€ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ ๋“ฑ๋กํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

function toggleLineThrough(e) {
  e.currentTarget.style.textDecoration = !e.currentTarget.style.textDecoration
    ? "line-through"
    : "";
}

li1.addEventListener("click", toggleLineThrough);
li2.addEventListener("click", toggleLineThrough);
li3.addEventListener("click", toggleLineThrough);

์ด ๋•Œ๋Š” li ์š”์†Œ๋“ค์ด ์ „๋ถ€ ๊ฐ™์€ ๋ถ€๋ชจ ์•„๋ž˜์— ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ถ€๋ชจ์—๊ฒŒ ์ด๋ฒคํŠธ ์œ„์ž„์„ ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ถ”์ฒœํ•œ๋‹ค. e.currentTaget์ด ์•„๋‹ˆ๋ผ e.target์„ ์‚ฌ์šฉํ•˜๊ณ  ul ์š”์†Œ์— ๋”ฑ ํ•œ ๋ฒˆ๋งŒ toggleLineThrough ํ•จ์ˆ˜๋ฅผ ๋“ฑ๋กํ•˜๋ฉด ๋œ๋‹ค.

function toggleLineThrough(e) {
  // e.target์€ ul์ด ์•„๋‹ˆ๋ผ ์ฒ˜์Œ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•œ li ์š”์†Œ๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค. 
  e.target.style.textDecoration = !e.target.style.textDecoration
    ? "line-through"
    : "";
}

ul.addEventListener("click", toggleLineThrough);