์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด ์ด๋ฒคํธ์ ๊ด๋ จ๋ ๋ค์ํ ์ ๋ณด๋ฅผ ๋ด๊ณ ์๋ ๊ฐ์ฒด
๊ฐ ๋์ ์ผ๋ก ์์ฑ๋๋ฉฐ ์ด๋ ๊ฒ ์์ฑ๋ ๊ฐ์ฒด๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ์ ์ฒซ๋ฒ์งธ ์ธ์๋ก ์ ๋ฌ
๋๋๋ฐ, ์ด ๊ฐ์ฒด๋ฅผ ์ ๋ฌ๋ฐ์ผ๋ ค๋ฉด ๋งค๊ฐ๋ณ์๋ฅผ ๋ช
์์ ์ผ๋ก ์ ์ธํด์ผ ํ๋ค.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Document</title>
</head>
<!--์ด๋ฒคํธ ํธ๋ค๋ฌ ์ดํธ๋ฆฌ๋ทฐํธ ๋ฐฉ์์ ๊ฒฝ์ฐ ๋งค๊ฐ๋ณ์ ์ด๋ฆ์ด event๊ฐ ์๋๋ฉด ์ด๋ฒคํธ ๊ฐ์ฒด๋ฅผ ์ ๋ฌ๋ฐ์ง ๋ชปํ๋ค.-->
<body onclick="showCoords(event)">
<p>ํด๋ฆญํ ๊ณณ์ ์ขํ๊ฐ ํ์๋ฉ๋๋ค.</p>
<em class="message"></em>
<script>
const $msg = document.querySelector(".message");
function showCoords(e) {
$msg.textContent = `clientX: ${e.clientX}, clientY: ${e.clientY}`;
}
</script>
</body>
</html>
Event ์ธํฐํ์ด์ค์ ์ด๋ฒคํธ ๊ด๋ จ ํ๋กํผํฐ๋ ๋ชจ๋ ์ด๋ฒคํธ ๊ฐ์ฒด๊ฐ ์์๋ฐ๋ ๊ณตํต ํ๋กํผํฐ์ด๋ค.
eventPhase
: ์ด๋ฒคํธ ์ ํ ๋จ๊ณ๋ฅผ ๋ํ๋ธ๋ค. (0: ์ด๋ฒคํธ ์์, 1: ์บก์ฒ๋ง ๋จ๊ณ, 2: ํ๊น ๋จ๊ณ, 3: ๋ฒ๋ธ๋ง ๋จ๊ณ)
target
: ์ด๋ฒคํธ๋ฅผ ๋ฐ์์ํจ ๊ฐ์ฒด๋ฅผ ๋ํ๋ธ๋ค.
currentTarget
: ์ด๋ฒคํธ ํธ๋ค๋ฌ๊ฐ ๋ฐ์ธ๋ฉ๋ DOM ์์๋ฅผ ๋ํ๋ธ๋ค.
cancelable
: preventDefault ๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ ์ด๋ฒคํธ์ ๊ธฐ๋ณธ ๋์์ ์ทจ์ํ ์ ์๋์ง ์ฌ๋ถ๋ฅผ ๋ํ๋๋ค. (false: ์ทจ์ํ ์ ์๋ค.)
DOM ์์ ๋
ธ๋์์ ๋ฐ์ํ ์ด๋ฒคํธ๋ DOM ํธ๋ฆฌ๋ฅผ ํตํด ์ ํ(propagation)
๋๋ค. ์ด๋ฅผ ์ด๋ฒคํธ ์ ํ๋ผ๊ณ ํ๋ค. ์ด๋ฒคํธ ์ ํ๋ ์ ํ๋๋ ๋ฐฉํฅ์ ๋ฐ๋ผ 3๊ฐ์ง๋ก ๊ตฌ๋ถํ ์ ์๋ค. ์ด๋ฒคํธ ๊ฐ์ฒด๋ window์์ ์์ํด์ ์ด๋ฒคํธ ํ๊น์ ํฅํด ์ ํ๋๋๋ฐ ์บก์ฒ๋ง-ํ๊น-๋ฒ๋ธ๋ง ์์์ด๋ค.
์ด๋ฒคํธ ํธ๋ค๋ฌ ์ดํธ๋ฆฌ๋ทฐํธ/ํ๋กํผํฐ ํํ๋ก ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋กํ ๊ฒฝ์ฐ์๋ ํ๊น๊ณผ ๋ฒ๋ธ๋ง ๋จ๊ณ์ ์ด๋ฒคํธ๋ง ์บ์นํ ์ ์๋ค. ์ด๋ฒคํธ ํธ๋ค๋ฌ ๋ฉ์๋ ๋ฐฉ์์ ์ธ๋ฒ์งธ ์ธ์๋ฅผ true๋ก ์ค์ ํ๋ฉด ์บก์ฒ๋ง ๋จ๊ณ์ ์ด๋ฒคํธ๋ฅผ ์ ๋ณ์ ์ผ๋ก ์บ์นํ ์ ์๋ค.
์บก์ฒ๋ง ๋จ๊ณ
: ์ด๋ฒคํธ๊ฐ ์์ ์์์์ ํ์ ์์๋ก ์ ํ
ํ๊น ๋จ๊ณ
: ์ด๋ฒคํธ๊ฐ ์ด๋ฒคํธ ํ๊น์ ๋๋ฌ
๋ฒ๋ธ๋ง ๋จ๊ณ
: ์ด๋ฒคํธ๊ฐ ํ์ ์์์์ ์์ ์์๋ก ์ ํ
์ด๋ฒคํธ ์์(delegation)
์ ์ฌ๋ฌ ๊ฐ์ ํ์ DOM ์์์ ๊ฐ๊ฐ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋กํ๋ ๋์ ํ๋์ ์์ ๋ ์์์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋กํ์ฌ ํ์ ์์์ ์ด๋ฒคํธ๋ฅผ ๋ชจ๋ ํธ๋ค๋งํ๋ ๋ฐฉ๋ฒ์ ๋งํ๋ค. ์ด ๋ฐฉ๋ฒ์ ์ฌ์ฉํ ๊ฒฝ์ฐ, ํ์์ ๋์ ์ผ๋ก ์ถ๊ฐ๋ ์์์ ๋ํด์๋ ๋์ผํ ๋ฐฉ์์ผ๋ก ์ด๋ฒคํธ๋ฅผ ํธ๋ค๋งํ ์ ์๋ค.
์ด๋ฒคํธ๋ฅผ ์ค์ ๋ฐ์์ํจ ์์๊ฐ ๊ฐ๋ฐ์๊ฐ ๊ธฐ๋ํ DOM ์์๊ฐ ์๋ ์ ์๊ธฐ ๋๋ฌธ์ ์ด๋ฒคํธ ํ๊น์ ๊ฒ์ฌํ ํ์๊ฐ ์๋ค.
์ด๋ฒคํธ๋ฅผ ์์์ ๋ฐ์ธ๋ฉํ ๊ฒฝ์ฐ, ์ด๋ฒคํธ ๊ฐ์ฒด์ target ํ๋กํผํฐ์ currentTarget ํ๋กํผํฐ๊ฐ ๋ค๋ฅผ ์ ์๋ค.
์ด๋ฒคํธ ๊ฐ์ฒด์ preventDefault
๋ฉ์๋๋ DOM ์์์ ๊ธฐ๋ณธ ๋์์ ์ค๋จ์ํจ๋ค.
์ด๋ฒคํธ ๊ฐ์ฒด์ stopPropagation ๋ฉ์๋๋ ์ด๋ฒคํธ ์ ํ๋ฅผ ์ค์ง์ํจ๋ค. stopPropagation
์ ํ์ DOM ์์์ ์ด๋ฒคํธ๋ฅผ ๊ฐ๋ณ์ ์ผ๋ก ์ฒ๋ฆฌํด์ผํ๋ ๊ฒฝ์ฐ์ ์ฌ์ฉํ ์ ์๋ค.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Document</title>
</head>
<body>
<!-- ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ํธ์ถํ ๋ ์ธ์๋ก ์ ๋ฌํ this๋ ์ด๋ฒคํธ๋ฅผ ๋ฐ์ธ๋ฉํ DOM ์์์ด๋ค.
์ด๋ฒคํธ ์ดํธ๋ฆฌ๋ทฐํธ ์ฐ์ธก์ ๋ด์ฉ์ onclick ํจ์ body์์ ์คํ๋ ๊ตฌ๋ฌธ์ด๋ค.
์ฆ์ ์คํ ํจ์(IIFE) ํํ๊ฐ ์๋ ๊ฒฝ์ฐ console.log(this)๋ ์คํ๋์ง ์๋๋ค.-->
<button class="button1" onclick="(() => console.log(this))(); handleClick1();">0</button>
<!--์ด๋ฒคํธ ํธ๋ค๋ฌ์ ์ฒซ ๋ฒ์งธ ๋งค๊ฐ๋ณ์์ ์ด๋ฆ์ด event๋ก ์๋ฌต์ ์ผ๋ก ๋ช
๋ช
๋๋ค.-->
<button class="button2" onclick="handleClick2(event)">0</button>
<button class="button3">0</button>
<button class="button4">0</button>
<script>
// ์ผ๋ฐํจ์๋ก ํธ์ถ๋๋ ํจ์ ๋ด๋ถ์ this๋ window์ด๋ค.
function handleClick1() {
console.log(this);
}
// ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ํตํด ์ ๋ฌ๋ฐ์ ์ธ์, e๋ ์ด๋ฒคํธ ๊ฐ์ฒด์ด๋ค.
// ํ์ดํ ํจ์๋ this๋ฅผ ๋ฐ์ธ๋ฉํ์ง ์๊ณ ์์ ์ค์ฝํ์ this๋ฅผ ๊ฐ๋ฆฌํจ๋ค.
// this๋ window์ด๋ค.
const handleClick2 = (e) => {
console.log(e);
console.log(this);
};
const $button3 = document.querySelector(".button3");
const $button4 = document.querySelector(".button4");
// ์ด๋ฒคํธ๋ฅผ ๋ฐ์ธ๋ฉํ DOM ์์๊ฐ this์ด๋ค.
$button3.onclick = function () {
console.log(this);
};
// ํ์ดํ ํจ์๋ this๋ฅผ ๋ฐ์ธ๋ฉํ๋ ๊ณผ์ ์ด ์ ์ธ๋จ,
// ์ ๊ทผํ๊ณ ์ํ๋ฉด ์ค์ฝํ์ฒด์ธ์ ๊ฐ์ฅ ๊ฐ๊น์ด this์ ์ ๊ทผํ์ฌ ๋ฐํํ๋ค.
// ํ์ดํ ํจ์๋ ์ฝ๋ฐฑ ํจ์ ๋ด์์ this๊ฐ ์ ์ญ๊ฐ์ฒด๋ฅผ ๊ฐ๋ฆฌํค๋ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํ ๋์์ผ๋ก ๋ํ๋ฌ๋ค.
$button4.addEventListener("click", () => {
console.log(this);
});
// console.log(1)์ return ๊ฐ์ด undefined์ด๋ค.
// console.log(1)์ด ๋ฐ์ธ๋ฉ ๊ณผ์ ์์ ์คํ์๋๋ ์ค์ ๋ก ๋ฐ์ธ๋ฉ๋ ํจ์๋ ์๋ค.
$button4.addEventListener("click", console.log(1));
</script>
</body>
</html>
์ด๋ฒคํธ ํธ๋ค๋ฌ ํ๋ฌํฐํฐ์ ์ด๋ฒคํธ ํธ๋ค๋ฌ ๋ฉ์๋ ๋ฐฉ์์ ๊ฒฝ์ฐ, ์ด๋ฒคํธ ํธ๋ค๋ฌ ๋ด๋ถ์ this๋ ์ด๋ฒคํธ๋ฅผ ๋ฐ์ธ๋ฉํ DOM ์์๋ฅผ ๊ฐ๋ฆฌํจ๋ค.
ํ์ดํ ํจ์๋ก ์ ์ํ ์ด๋ฒคํธ ํธ๋ค๋ฌ ๋ด๋ถ์ this๋ ์์ ์ค์ฝํ์ this๋ฅผ ๊ฐ๋ฆฌํจ๋ค. ํ์ดํ ํจ์๋ ํจ์ ์์ฒด์ this ๋ฐ์ธ๋ฉ์ ๊ฐ์ง ์๋๋ค.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<button>0</button>
</body>
<script>
const $button = document.querySelector("button");
// this๋ ์ด๋ฒคํธ๋ฅผ ๋ฐ์ธ๋ฉํ DOM ์์๋ฅผ ๊ฐ๋ฆฌํจ๋ค. <button>0</button>
$button.addEventListener("click", function (e) {
console.log(this);
});
// this๋ ์์ ์ค์ฝํ์ this๋ฅผ ๊ฐ๋ฆฌํจ๋ค. window
$button.addEventListener("click", (e) => {
console.log(this);
});
</script>
</html>
class์์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฐ์ธ๋ฉํ ๊ฒฝ์ฐ
, ์ผ๋ฐ ํจ์์ this๋ class๊ฐ ์์ฑํ ์ธ์คํด์ค๋ฅผ ๊ฐ๋ฆฌํค์ง ์๋๋ค. ์ด๋ฒคํธ ํธ๋ค๋ฌ ๋ด๋ถ์ this๋ ์ด๋ฒคํธ๋ฅผ ๋ฐ์ธ๋ฉํ DOM ์์๋ฅผ ๊ฐ๋ฆฌํคํค ๋๋ฌธ์ ๋ณ๋๋ก this(์์ฑํ ์ธ์คํด์ค)๋ฅผ bind ๊ณผ์ ์ด ํ์ํ๋ค. ๋จ, ํ์ดํ ํจ์์ ๊ฒฝ์ฐ๋ ํจ์๊ฐ ์ธ์คํด์ค์ ๋ฉ์๋๋ก์ ๋์ํ๊ธฐ ๋๋ฌธ์ ๋ณ๋์ bind ๊ณผ์ ์ด ํ์์๋ค.<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<button class="btn1">0</button>
<button class="btn2">0</button>
<button class="btn3">0</button>
<script>
class App {
constructor() {
this.$button1 = document.querySelector(".btn1");
this.$button2 = document.querySelector(".btn2");
this.$button3 = document.querySelector(".btn3");
this.count1 = 0;
this.count2 = 0;
this.count3 = 0;
this.$button1.onclick = this.increase1;
// increase2 ๋ฉ์๋ ๋ด๋ถ์ this๊ฐ ํด๋์ค๊ฐ ์์ฑํ ์ธ์คํด์ค๋ฅผ ๊ฐ๋ฆฌํค๋๋ก ํ๋ค.
this.$button2.onclick = this.increase2.bind(this);
this.$button3.onclick = this.increase3;
}
increase1() {
// ์ด๋ฒคํธ ํธ๋ค๋ฌ ๋ด๋ถ์ this๋ ์ด๋ฒคํธ๋ฅผ ๋ฐ์ธ๋ฉํ DOM ์์๋ฅผ ๊ฐ๋ฆฌํจ๋ค.
// ์ฌ๊ธฐ์ this๋ this.$button ์ด๋ค.
console.log("increase1");
this.$button1.textContent = ++this.count1;
}
increase2() {
// this๋ ํด๋์ค๊ฐ ์์ฑํ ์ธ์คํด์ค๋ฅผ ๊ฐ๋ฆฌํจ๋ค.
console.log("increase2");
this.$button2.textContent = ++this.count2;
}
// increase3๋ ํ๋กํ ํ์
์ ๋ฉ์๋๊ฐ ์๋๋ผ ์ธ์คํด์ค์ ๋ฉ์๋๋ก์ ๋์ํ๋ค.
increase3 = () => {
// ํ์ดํ ํจ์์ this๋ ์์ ์ค์ฝํ์ this๋ฅผ ๊ฐ๋ฆฌํจ๋ค.
console.log("increase3");
this.$button3.textContent = ++this.count3;
};
}
new App();
</script>
</body>
</html>
์ถ์ฒ: ๋ชจ๋ ์๋ฐ์คํฌ๋ฆฝํธ Deep Dive-์ด์ ๋ชจ