๋ธ๋ผ์ฐ์ ๋ ์ฒ๋ฆฌํด์ผํ ํน์ ์ฌ๊ฑด์ด ๋ฐ์ํ๋ฉด ์ด๋ฅผ ๊ฐ์งํ์ฌ ์ด๋ฒคํธ(event)๋ฅผ ๋ฐ์(trigger)์ํจ๋ค. ๋ง์ฝ ์ ํ๋ฆฌ์ผ์ด์ ์ด ํน์ ํ์ ์ ์ด๋ฒคํธ์ ๋ํด ๋ฐ์ํ์ฌ ์ด๋ค ์ผ์ ํ๊ณ ์ถ๋ค๋ฉด ํด๋นํ๋ ํ์ ์ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ์ ๋ ํธ์ถ๋ ํจ์๋ฅผ ๋ธ๋ผ์ฐ์ ์๊ฒ ์๋ ค ํธ์ถ์ ์์ํ๋ค. ์ด๋ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ์ ๋ ํธ์ถ๋ ํจ์๋ฅผ ์ด๋ฒคํธ ํธ๋ค๋ฌ(event handler)๋ผ ํ๊ณ , ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ์ ๋ ๋ธ๋ผ์ฐ์ ์๊ฒ ์ด๋ฒคํธ ํธ๋ค๋ฌ์ ํธ์ถ์ ์์ํ๋ ๊ฒ์ ์ด๋ฒคํธ ํธ๋ค๋ฌ ๋ฑ๋ก์ด๋ผ ํ๋ค.
<!DOCTYPE html>
<html>
<body>
<button>Click me!</button>
<script>
const $button = document.querySelector('button');
// ์ฌ์ฉ์๊ฐ ๋ฒํผ์ ํด๋ฆญํ๋ฉด ํจ์๋ฅผ ํธ์ถํ๋๋ก ์์ฒญ
$button.onclick = () => { alert('button click'); };
</script>
</body>
</html>
์ ์์ ์์ ๋ฒํผ์์ $button์ onclick ํ๋กํผํฐ์ ํจ์๋ฅผ ํ ๋นํ๋ค. ์ด ์ด๋ฒคํธ ํธ๋ค๋ฌ ํ๋กํผํฐ์ ํจ์๋ฅผ ํ ๋นํ๋ฉด ํด๋น ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ์ ๋ ํ ๋นํ ํจ์๊ฐ ๋ธ๋ผ์ฐ์ ์ ์ํด ํธ์ถ๋๋ค.
์ด์ฒ๋ผ ์ด๋ฒคํธ์ ๊ทธ์ ๋์ํ๋ ํจ์ (์ด๋ฒคํธ ํธ๋ค๋ฌ)๋ฅผ ํตํด ์ฌ์ฉ์์ ์ ํ๋ฆฌ์ผ์ด์
์ ์ํธ์์ฉ์ ํ ์ ์๋ค. ์ด์ ๊ฐ์ด ํ๋ก๊ทธ๋จ์ ํ๋ฆ์ ์ด๋ฒคํธ ์ค์ฌ์ผ๋ก ์ ์ดํ๋ ํ๋ก๊ทธ๋๋ฐ ๋ฐฉ์์ ์ด๋ฒคํธ ๋๋ฆฌ๋ธ ํ๋ก๊ทธ๋๋ฐ(event-driven programming)์ด๋ผ ํ๋ค.
์ด๋ฒคํธ ํ์ ์ ์ด๋ฒคํธ์ ์ข ๋ฅ๋ฃฐ ๋ํ๋ด๋ ๋ฌธ์์ด์ด๋ค.
์ด๋ฒคํธ ํธ๋ค๋ฌ๋ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ์ ๋ ๋ธ๋ผ์ฐ์ ์ ํธ์ถ์ ์์ํ ํจ์๋ค. ๋ค์ ๋งํด, ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด ๋ธ๋ผ์ฐ์ ์ ์ํด ํธ์ถ๋ ํจ์๊ฐ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ค. ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ์ ๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ์ ํธ์ถ์ ์์ํ๋ ๊ฒ์ ์ด๋ฒคํธ ํธ๋ค๋ฌ ๋ฑ๋ก์ด๋ผ ํ๋ค. ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋กํ๋ ๋ฐฉ๋ฒ์ 3๊ฐ์ง๋ค.
HTML ์์์ ์ดํธ๋ฆฌ๋ทฐํธ ์ค์๋ ์ด๋ฒคํธ์ ๋์ํ๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ ์ดํธ๋ฆฌ๋ทฐํธ๊ฐ ์๋ค. ์ด๋ฒคํธ ํธ๋ค๋ฌ ์ดํธ๋ฆฌ๋ทฐํธ์ ์ด๋ฆ์ onclick๊ณผ ๊ฐ์ด on ์ ๋์ฌ์ ์ด๋ฒคํธ์ ์ข ๋ฅ๋ฅผ ๋ํ๋ด๋ ์ด๋ฒคํธ ํ์ ์ผ๋ก ์ด๋ฃจ์ด์ ธ ์๋ค. ์ด๋ฒคํธ ํธ๋ค๋ฌ ์ดํธ๋ฆฌ๋ทฐํธ ๊ฐ์ผ๋ก ํจ์ ํธ์ถ๋ฌธ ๋ฑ์ ๋ฌธ์ ํ ๋นํ๋ฉด ์ด๋ฒคํธ ํธ๋ค๋ฌ๊ฐ ๋ฑ๋ก๋๋ค. ์ฆ, ์ด๋ฒคํธ ๋์์ ํ๊ทธ ์์ฑ์ผ๋ก ์ง์ ํ๋ ๊ฒ์ด๋ค.
<!DOCTYPE html>
<html>
<body>
<button onclick="sayHi('Lee')">Click me!</button>
<script>
function sayHi(name) {
console.log(`Hi! ${name}.`);
}
</script>
</body>
</html>
window ๊ฐ์ฒด์ Document, HTMLElement ํ์ ์ DOM ๋ ธ๋ ๊ฐ์ฒด๋ ์ด๋ฒคํธ์ ๋์ํ๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ ํ๋กํผํฐ๋ฅผ ๊ฐ์ง๊ณ ์๋ค. ์ด๋ฒคํธ ํธ๋ค๋ฌ ํ๋กํผํฐ์ ํค๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ ์ดํธ๋ฆฌ๋ทฐํธ์ ๋ง์ฐฌ๊ฐ์ง๋ก onclick๊ณผ ๊ฐ์ด on์ ๋์ฌ์ ์ด๋ฒคํธ์ ์ข ๋ฅ๋ฅผ ๋ํ๋ด๋ ์ด๋ฒคํธ ํ์ ์ผ๋ก ์ด๋ฃจ์ด์ ธ ์๋ค. ์ด๋ฒคํธ ํธ๋ค๋ฌ ํ๋กํผํฐ์ ํจ์๋ฅผ ๋ฐ์ธ๋ฉํ๋ฉด ์ด๋ฒคํธ ํธ๋ค๋ฌ๊ฐ ๋ฑ๋ก๋๋ค.
<!DOCTYPE html>
<html>
<body>
<button>Click me!</button>
<script>
const $button = document.querySelector('button');
// ์ด๋ฒคํธ ํธ๋ค๋ฌ ํ๋กํผํฐ์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฐ์ธ๋ฉ
$button.onclick = function () {
console.log('button click');
};
</script>
</body>
</html>
์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋กํ๊ธฐ ์ํด์๋ ์ด๋ฒคํธ๋ฅผ ๋ฐ์์ํฌ ๊ฐ์ฒด์ธ ์ด๋ฒคํ ํ๊น(event target)๊ณผ ์ด๋ฒคํธ์ ์ข ๋ฅ๋ฅผ ๋ํ๋ด๋ ๋ฌธ์์ด์ธ ์ด๋ฒคํธ ํ์ (event type) ๊ทธ๋ฆฌ๊ณ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ์ง์ ํ ํ์๊ฐ ์๋ค. ์๋ฅผ ๋ค์ด, ๋ฒํผ ์์๊ฐ ํด๋ฆญ๋๋ฉด handleClick ํจ์๋ฅผ ํธ์ถํ๋๋ก ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋กํ๋ ๊ฒฝ์ฐ ์ด๋ฒคํธ ํ๊น์ ๋ฒํผ ์์์ด๊ณ ์ด๋ฒคํธ ํ์ ์ โclickโ์ด๋ฉฐ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ handleClick ํจ์๋ค.
์ด๋ฒคํธ ํธ๋ค๋ฌ๋ ๋๋ถ๋ถ ์ด๋ฒคํธ๋ฅผ ๋ฐ์์ํฌ ์ด๋ฒคํธ ํ๊น์ ๋ฐ์ธ๋ฉํ๋ค. ํ์ง๋ง ๋ฐ๋์ ์ด๋ฒคํธ ํ๊น์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฐ์ธ๋ฉํด์ผ ํ๋ ๊ฒ์ ์๋๋ค. ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ ์ด๋ฒคํธ ํ๊น ๋๋ ์ ํ๋ ์ด๋ฒคํธ๋ฅผ ์บ์นํ DOM ๋ ธ๋ ๊ฐ์ฒด์ ๋ฐ์ธ๋ฉํ๋ค.
์์ ์ดํด๋ณธ โ์ด๋ฒคํธ ํธ๋ค๋ฌ ์ดํธ๋ฆฌ๋ทฐํธ ๋ฐฉ์โ๋ ๊ฒฐ๊ตญ DOM ๋ ธ๋ ๊ฐ์ฒด์ ์ด๋ฒคํธ ํธ๋ค๋ฌ ํ๋กํผํฐ๋ก ๋ณํ๋๋ฏ๋ก ๊ฒฐ๊ณผ์ ์ผ๋ก ์ด๋ฒคํธ ํธ๋ค๋ฌ ํ๋กํผํฐ ๋ฐฉ์๊ณผ ๋์ผํ๋ค๊ณ ๋ณผ ์ ์๋ค. โ์ด๋ฒคํธ ํธ๋ค๋ฌ ํ๋กํผํฐ ๋ฐฉ์โ์ โ์ด๋ฒคํธ ํธ๋ค๋ฌ ์ดํธ๋ฆฌ๋ทฐํธ ๋ฐฉ์โ์ HTML๊ณผ ์๋ฐ์คํฌ๋ฆฝํธ๊ฐ ๋ค์์ด๋ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์๋ค. ํ์ง๋ง ์ด๋ฒคํธ ํธ๋ค๋ฌ ํ๋กํผํฐ์ ํ๋์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ง ๋ฐ์ธ๋ฉํ ์ ์๋ค๋ ๋จ์ ์ด ์๋ค.
<!DOCTYPE html>
<html>
<body>
<button>Click me!</button>
<script>
const $button = document.querySelector('button');
// ์ด๋ฒคํธ ํธ๋ค๋ฌ ํ๋กํผํฐ ๋ฐฉ์์ ํ๋์ ์ด๋ฒคํธ์ ํ๋์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ง์ ๋ฐ์ธ๋ฉํ ์ ์๋ค.
// ์ฒซ ๋ฒ์งธ๋ก ๋ฐ์ธ๋ฉ๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ ๋ ๋ฒ์งธ ๋ฐ์ธ๋ฉ๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ์ ์ํด ์ฌํ ๋น๋์ด
// ์คํ๋์ง ์๋๋ค.
$button.onclick = function () {
console.log('Button clicked 1');
};
// ๋ ๋ฒ์งธ๋ก ๋ฐ์ธ๋ฉ๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ
$button.onclick = function () {
console.log('Button clicked 2');
};
</script>
</body>
</html>
addEventListener
๋ฉ์๋ ๋ฐฉ์addEventListener
๋ฉ์๋์ ์ฒซ ๋ฒ์งธ ๋งค๊ฐ๋ณ์์๋ ์ด๋ฒคํธ์ ์ข
๋ฅ๋ฅผ ๋ํ๋ด๋ ๋ฌธ์์ด์ธ ์ด๋ฒคํธ ํ์
,๋ ๋ฒ์งธ ๋งค๊ฐ๋ณ์์๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ(ํจ์), ๋ง์ง๋ง ๋งค๊ฐ๋ณ์์๋ ์ด๋ฒคํธ๋ฅผ ์บ์นํ ์ ํ ๋จ๊ณ(์บก์ฒ๋ง ๋๋ ๋ฒ๋ธ๋ง)๋ฅผ ์ง์ ํ๋ค.
<!DOCTYPE html>
<html>
<body>
<button>Click me!</button>
<script>
const $button = document.querySelector('button');
// ์ด๋ฒคํธ ํธ๋ค๋ฌ ํ๋กํผํฐ ๋ฐฉ์
// $button.onclick = function () {
// console.log('button click');
// };
// addEventListener ๋ฉ์๋ ๋ฐฉ์
$button.addEventListener('click', function () {
console.log('button click');
});
</script>
</body>
</html>
๋์ผํ HTML ์์์์ ๋ฐ์ํ ๋์ผํ ์ด๋ฒคํธ์ ๋ํด ์ด๋ฒคํธ ํธ๋ค๋ฌ ํ๋กํผํฐ ๋ฐฉ์์ ํ๋ ์ด์์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋กํ ์ ์์ง๋ง addEventListener
๋ฉ์๋๋ ํ๋ ์ด์์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋กํ ์ ์๋ค. ์ด๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ ๋ฑ๋ก๋ ์์๋๋ก ํธ์ถ๋๋ค. addEventListener
๋ฉ์๋๋ฅผ ํตํด ์ฐธ์กฐ๊ฐ ๋์ผํ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ์ค๋ณต ๋ฑ๋กํ๋ฉด ํ๋์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ง ๋ฑ๋ก๋๋ค.
<!DOCTYPE html>
<html>
<body>
<button>Click me!</button>
<script>
const $button = document.querySelector('button');
const handleClick = () => console.log("button click");
// addEventListener ๋ฉ์๋๋ ๋์ผํ ์์์์ ๋ฐ์ํ ๋์ผํ ์ด๋ฒคํธ์ ๋ํด
// ํ๋ ์ด์์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋กํ ์ ์๋ค.
$button.addEventListener('click', function () {
console.log('[1]button click');
});
$button.addEventListener('click', function () {
console.log('[2]button click');
});
// ์ฐธ์กฐ๊ฐ ๋์ผํ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ์ค๋ณต ๋ฑ๋กํ๋ฉด ํ๋์ ํธ๋ค๋ฌ๋ง ๋ฑ๋ก๋๋ค.
$button.addEventListener('click', handleClick);
$button.addEventListener('click', handleClick);
</script>
</body>
</html>
addEventListener
๋ฉ์๋๋ก ๋ฑ๋กํ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ์ ๊ฑฐํ๋ ค๋ฉด EventTarget.prototype.removeEventListen
๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ค. removeEventListener
๋ฉ์๋์ ์ ๋ฌํ ์ธ์๋ addEventListener
๋ฉ์๋์ ๋์ผํ๋ค. ๋จ addEventListener
๋ฉ์๋์ ์ ๋ฌํ ์ธ์์ removeEventListener
๋ฉ์๋์ ์ ๋ฌํ ์ธ์๊ฐ ์ผ์นํ์ง ์์ผ๋ฉด ์ด๋ฒคํธ ํธ๋ค๋ฌ๊ฐ ์ ๊ฑฐ๋์ง ์๋๋ค. ๋ฐ๋ผ์ ๋ฌด๋ช
ํจ์๋ฅผ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ก ๋ฑ๋กํ ๊ฒฝ์ฐ ์ ๊ฑฐํ ์ ์๋ค.
<!DOCTYPE html>
<html>
<body>
<button>Click me!</button>
<script>
const $button = document.querySelector('button');
const handleClick = () => console.log('button click');
// ์ด๋ฒคํธ ํธ๋ค๋ฌ ๋ฑ๋ก
$button.addEventListener('click', handleClick);
// ์ด๋ฒคํธ ํธ๋ค๋ฌ ์ ๊ฑฐ
// addEventListener ๋ฉ์๋์ ์ ๋ฌํ ์ธ์์ removeEventListener ๋ฉ์๋์
// ์ ๋ฌํ ์ธ์๊ฐ ์ผ์นํ์ง ์์ผ๋ฉด ์ด๋ฒคํธ ํธ๋ค๋ฌ๊ฐ ์ ๊ฑฐ๋์ง ์๋๋ค.
$button.removeEventListener('click', handleClick, true); // ์คํจ
$button.removeEventListener('click', handleClick); // ์ฑ๊ณต
</script>
</body>
</html>
์ด๋ฒคํธ ํธ๋ค๋ฌ ํ๋กํผํฐ ๋ฐฉ์์ผ๋ก ๋ฑ๋กํ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ removeEventListener
๋ฉ์๋๋ก ์ ๊ฑฐํ ์ ์๋ค. ์ด๋ฒคํธ ํธ๋ค๋ฌ ํ๋กํผํฐ ๋ฐฉ์์ผ๋ก ๋ฑ๋กํ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ์ ๊ฑฐํ๋ ค๋ฉด ์ด๋ฒคํธ ํธ๋ค๋ฌ ํ๋กํผํฐ์ null์ ํ ๋นํ๋ค.
<!DOCTYPE html>
<html>
<body>
<button>Click me!</button>
<script>
const $button = document.querySelector('button');
const handleClick = () => console.log('button click');
// ์ด๋ฒคํธ ํธ๋ค๋ฌ ํ๋กํผํฐ ๋ฐฉ์์ผ๋ก ์ด๋ฒคํธ ํธ๋ค๋ฌ ๋ฑ๋ก
$button.onclick = handleClick;
// removeEventListener ๋ฉ์๋๋ก ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ์ ๊ฑฐํ ์ ์๋ค.
$button.removeEventListener('click', handleClick);
// ์ด๋ฒคํธ ํธ๋ค๋ฌ ํ๋กํผํฐ์ null์ ํ ๋นํ์ฌ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ์ ๊ฑฐํ๋ค.
$button.onclick = null;
</script>
</body>
</html>
์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด ์ด๋ฒคํธ์ ๊ด๋ จํ ๋ค์ํ ์ ๋ณด๋ฅผ ๋ด๊ณ ์๋ ์ด๋ฒคํธ ๊ฐ์ฒด๊ฐ ๋์ ์ผ๋ก ์์ฑ๋๋ค. ์์ฑ๋ ์ด๋ฒคํธ ๊ฐ์ฒด๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ์ ์ฒซ ๋ฒ์งธ ์ธ์๋ก ์ ๋ฌ๋๋ค.
<!DOCTYPE html>
<html>
<body>
<p>ํด๋ฆญํ์ธ์. ํด๋ฆญํ ๊ณณ์ ์ขํ๊ฐ ํ์๋ฉ๋๋ค.</p>
<em class="message"></em>
<script>
const $msg = document.querySelector('.message');
// ํด๋ฆญ ์ด๋ฒคํธ์ ์ํด ์์ฑ๋ ์ด๋ฒคํธ ๊ฐ์ฒด๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ์ ์ฒซ ๋ฒ์งธ ์ธ์๋ก ์ ๋ฌ๋๋ค.
function showCoords(e) {
$msg.textContent = `clientX: ${e.clientX}, clientY: ${e.clientY}`;
}
document.onclick = showCoords;
</script>
</body>
</html>
ํด๋ฆญ ์ด๋ฒคํธ์ ์ํด ์์ฑ๋ ์ด๋ฒคํธ ๊ฐ์ฒด๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ์ ์ฒซ ๋ฒ์งธ ์ธ์๋ก ์ ๋ฌ๋์ด ๋งค๊ฐ๋ณ์ e์ ์๋ฌต์ ์ผ๋ก ํ ๋น๋๋ค.
<!DOCTYPE html>
<html>
<head>
<style>
html, body { height: 100%; }
</style>
</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์ฌ์ผ ํ๋ค.
์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด ์ด๋ฒคํธ ํ์
์ ๋ฐ๋ผ ๋ค์ํ ํ์
์ ์ด๋ฒคํธ ๊ฐ์ฒด๊ฐ ์์ฑ๋๋ค. ์ด๋ฒคํธ ๊ฐ์ฒด๋ ๋ค์๊ณผ ๊ฐ์ ์์ ๊ตฌ์กฐ๋ฅผ ๊ฐ๋๋ค. ์์ฑ๋ ์ด๋ฒคํธ ๊ฐ์ฒด๋ ์์ฑ์ ํจ์์ ๋๋ถ์ด ์์ฑ๋๋ ํ๋กํ ํ์
์ผ๋ก ๊ตฌ์ฑ๋ ํ๋กํ ํ์
์ฒด์ธ์ ์ผ์์ด ๋๋ค.
<!DOCTYPE html>
<html>
<body>
<script>
// Event ์์ฑ์ ํจ์๋ฅผ ํธ์ถํ์ฌ foo ์ด๋ฒคํธ ํ์
์ Event ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ค.
let e = new Event('foo');
console.log(e);
// Event {isTrusted: false, type: "foo", target: null, ...}
console.log(e.type); // "foo"
console.log(e instanceof Event); // true
console.log(e instanceof Object); // true
// FocusEvent ์์ฑ์ ํจ์๋ฅผ ํธ์ถํ์ฌ focus ์ด๋ฒคํธ ํ์
์ FocusEvent ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ค.
e = new FocusEvent('focus');
console.log(e);
// FocusEvent {isTrusted: false, relatedTarget: null, view: null, ...}
// MouseEvent ์์ฑ์ ํจ์๋ฅผ ํธ์ถํ์ฌ click ์ด๋ฒคํธ ํ์
์ MouseEvent ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ค.
e = new MouseEvent('click');
console.log(e);
// MouseEvent {isTrusted: false, screenX: 0, screenY: 0, clientX: 0, ... }
// KeyboardEvent ์์ฑ์ ํจ์๋ฅผ ํธ์ถํ์ฌ keyup ์ด๋ฒคํธ ํ์
์ KeyboardEvent ๊ฐ์ฒด๋ฅผ
// ์์ฑํ๋ค.
e = new KeyboardEvent('keyup');
console.log(e);
// KeyboardEvent {isTrusted: false, key: "", code: "", ctrlKey: false, ...}
// InputEvent ์์ฑ์ ํจ์๋ฅผ ํธ์ถํ์ฌ change ์ด๋ฒคํธ ํ์
์ InputEvent ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ค.
e = new InputEvent('change');
console.log(e);
// InputEvent {isTrusted: false, data: null, inputType: "", ...}
</script>
</body>
</html>
Event ์ธํฐํ์ด์ค๋ DOM ๋ด์์ ๋ฐ์ํ ์ด๋ฒคํธ์ ์ํด ์์ฑ๋๋ ์ด๋ฒคํธ ๊ฐ์ฒด๋ฅผ ๋ํ๋ธ๋ค. Event ์ธํฐํ์ด์ค์๋ ๋ชจ๋ ์ด๋ฒคํธ ๊ฐ์ฒด์ ๊ณตํต ํ๋กํผํฐ๊ฐ ์ ์๋์ด ์๊ณ FocusEvent
, MouseEvent
, KeyboardEvent
, WheelEvent
๊ฐ์ ํ์ ์ธํฐํ์ด์ค์๋ ์ด๋ฒคํธ ํ์
์ ๋ฐ๋ผ ๊ณ ์ ํ ํ๋กํผํฐ๊ฐ ์ ์๋์ด ์๋ค. ์ฆ, ๋ค์ ์์ ์ ๊ฐ์ด ์ด๋ฒคํธ ๊ฐ์ฒด์ ํ๋กํผํฐ๋ ๋ฐ์ํ ์ด๋ฒคํธ์ ํ์
์ ๋ฐ๋ผ ๋ฌ๋ผ์ง๋ค
<!DOCTYPE html>
<html>
<body>
<input type="text">
<input type="checkbox">
<button>Click me!</button>
<script>
const $input = document.querySelector('input[type=text]');
const $checkbox = document.querySelector('input[type=checkbox]');
const $button = document.querySelector('button');
// load ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด Event ํ์
์ ์ด๋ฒคํธ ๊ฐ์ฒด๊ฐ ์์ฑ๋๋ค.
window.onload = console.log;
// change ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด Event ํ์
์ ์ด๋ฒคํธ ๊ฐ์ฒด๊ฐ ์์ฑ๋๋ค.
$checkbox.onchange = console.log;
// focus ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด FocusEvent ํ์
์ ์ด๋ฒคํธ ๊ฐ์ฒด๊ฐ ์์ฑ๋๋ค.
$input.onfocus = console.log;
// input ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด InputEvent ํ์
์ ์ด๋ฒคํธ ๊ฐ์ฒด๊ฐ ์์ฑ๋๋ค.
$input.oninput = console.log;
// keyup ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด KeyboardEvent ํ์
์ ์ด๋ฒคํธ ๊ฐ์ฒด๊ฐ ์์ฑ๋๋ค.
$input.onkeyup = console.log;
// click ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด MouseEvent ํ์
์ ์ด๋ฒคํธ ๊ฐ์ฒด๊ฐ ์์ฑ๋๋ค.
$button.onclick = console.log;
</script>
</body>
</html>
Event ์ธํฐํ์ด์ค์ ์ด๋ฒคํธ ๊ด๋ จ ํ๋กํผํฐ๋ ๋ชจ๋ ์ด๋ฒคํธ ๊ฐ์ฒด๊ฐ ์์๋ฐ๋ ๊ณตํต ํ๋กํผํฐ์ด๋ค. ์ด๋ฒคํธ ๊ฐ์ฒด์ ๊ณตํต ํ๋กํผํฐ๋ ๋ค์๊ณผ ๊ฐ๋ค.
<!DOCTYPE html>
<html>
<body>
<input type="checkbox">
<em class="message">off</em>
<script>
const $checkbox = document.querySelector('input[type=checkbox]');
const $msg = document.querySelector('.message');
// change ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด Event ํ์
์ ์ด๋ฒคํธ ๊ฐ์ฒด๊ฐ ์์ฑ๋๋ค.
$checkbox.onchange = e => {
console.log(Object.getPrototypeOf(e) === Event.prototype); // true
// e.target์ change ์ด๋ฒคํธ๋ฅผ ๋ฐ์์ํจ DOM ์์ $checkbox๋ฅผ ๊ฐ๋ฆฌํค๊ณ
// e.target.checked๋ ์ฒดํฌ๋ฐ์ค ์์์ ํ์ฌ ์ฒดํฌ ์ํ๋ฅผ ๋ํ๋ธ๋ค.
$msg.textContent = e.target.checked ? 'on' : 'off';
};
</script>
</body>
</html>
click, dbclick, mousedown, mouseup, mousemove, mouseenter, mouseleave ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด ์์ฑ๋๋ MouseEvent ํ์ ์ ์ด๋ฒคํธ ๊ฐ์ฒด๋ ๋ค์๊ณผ ๊ฐ์ ๊ณ ์ ์ ํ๋กํผํฐ๋ฅผ ๊ฐ๋๋ค.
<!DOCTYPE html>
<html>
<head>
<style>
.box {
width: 100px;
height: 100px;
background-color: #fff700;
border: 5px solid orange;
cursor: pointer;
}
</style>
</head>
<body>
<div class="box"></div>
<script>
// ๋๋๊ทธ ๋์ ์์
const $box = document.querySelector('.box');
// ๋๋๊ทธ ์์ ์์ ์ ๋ง์ฐ์ค ํฌ์ธํฐ ์์น
const initialMousePos = { x: 0, y: 0 };
// ์คํ์
: ์ด๋ํ ๊ฑฐ๋ฆฌ
const offset = { x: 0, y: 0 };
// mousemove ์ด๋ฒคํธ ํธ๋ค๋ฌ
const move = e => {
// ์คํ์
= ํ์ฌ(๋๋๊ทธํ๊ณ ์๋ ์์ ) ๋ง์ฐ์ค ํฌ์ธํฐ ์์น - ๋๋๊ทธ ์์ ์์ ์ ๋ง์ฐ์ค ํฌ์ธํฐ ์์น
offset.x = e.clientX - initialMousePos.x;
offset.y = e.clientY - initialMousePos.y;
// translate3d๋ GPU๋ฅผ ์ฌ์ฉํ๋ฏ๋ก absolute์ top, left๋ฅผ ์ฌ์ฉํ๋ ๊ฒ๋ณด๋ค ๋น ๋ฅด๋ค.
// top, left๋ ๋ ์ด์์์ ์ํฅ์ ์ค๋ค.
$box.style.transform = `translate3d(${offset.x}px, ${offset.y}px, 0)`;
};
// mousedown ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด ๋๋๊ทธ ์์ ์์ ์ ๋ง์ฐ์ค ํฌ์ธํฐ ์ขํ๋ฅผ ์ ์ฅํ๋ค.
$box.addEventListener('mousedown', e => {
// ์ด๋ ๊ฑฐ๋ฆฌ๋ฅผ ๊ณ์ฐํ๊ธฐ ์ํด mousedown ์ด๋ฒคํธ๊ฐ ๋ฐ์(๋๋๊ทธ๋ฅผ ์์)ํ๋ฉด
// ๋๋๊ทธ ์์ ์์ ์ ๋ง์ฐ์ค ํฌ์ธํฐ ์ขํ(e.clientX/e.clientY: ๋ทฐํฌํธ ์์์ ํ์ฌ
// ๋ง์ฐ์ค์ ํฌ์ธํฐ ์ขํ)๋ฅผ ์ ์ฅํด ๋๋ค. ํ๋ฒ ์ด์ ๋๋๊ทธ๋ก ์ด๋ํ ๊ฒฝ์ฐ move์์
// translate3d(${offset.x}px, ${offset.y}px, 0)์ผ๋ก ์ด๋ํ ์ํ์ด๋ฏ๋ก
// offset.x์ offset.y๋ฅผ ๋นผ์ฃผ์ด์ผ ํ๋ค.
initialMousePos.x = e.clientX - offset.x;
initialMousePos.y = e.clientY - offset.y;
// mousedown ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ ์ํ์์ mousemove ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด
// box ์์๋ฅผ ์ด๋์ํจ๋ค.
document.addEventListener('mousemove', move);
});
// mouseup ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด mousemove ์ด๋ฒคํธ๋ฅผ ์ ๊ฑฐํด ์ด๋์ ๋ฉ์ถ๋ค.
document.addEventListener('mouseup', () => {
document.removeEventListener('mousemove', move);
});
</script>
</body>
</html>
keydown, keyup, keypress ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด ์์ฑ๋๋ KeyboardEvent ํ์ ์ ์ด๋ฒคํธ ๊ฐ์ฒด๋ altKey, ctrlKey, shiftKey, metaKey, key, keyCode ๊ฐ์ ๊ณ ์ ์ ํ๋กํผํฐ๋ฅผ ๊ฐ๋๋ค.
<!DOCTYPE html>
<html>
<body>
<input type="text" />
<em class="message"></em>
<script>
const $input = document.querySelector('input[type=text]');
const $msg = document.querySelector('.message');
$input.onkeyup = e => {
// e.key๋ ์
๋ ฅํ ํค ๊ฐ์ ๋ฌธ์์ด๋ก ๋ฐํํ๋ค.
// ์
๋ ฅํ ํค๊ฐ 'Enter', ์ฆ ์ํฐ ํค๊ฐ ์๋๋ฉด ๋ฌด์ํ๋ค.
if (e.key !== 'Enter') return;
// ์ํฐํค๊ฐ ์
๋ ฅ๋๋ฉด ํ์ฌ๊น์ง ์
๋ ฅ ํ๋์ ์
๋ ฅ๋ ๊ฐ์ ์ถ๋ ฅํ๋ค.
$msg.textContent = e.target.value;
e.target.value = '';
};
</script>
</body>
</html>
DOM ํธ๋ฆฌ ์์ ์กด์ฌํ๋ DOM ์์ ๋ ธ๋์์ ๋ฐ์ํ ์ด๋ฒคํธ๋ DOM ํธ๋ฆฌ๋ฅผ ํตํด ์ ํ๋๋ค. ์ด๋ฅผ ์ด๋ฒคํธ ์ ํ(event propagation)๋ผ๊ณ ํ๋ค.
<!DOCTYPE html>
<html>
<body>
<ul id="fruits">
<li id="apple">Apple</li>
<li id="banana">Banana</li>
<li id="orange">Orange</li>
</ul>
</body>
</html>
์ด๋ฒคํธ ์ ํ๋ ์ด๋ฒคํธ ๊ฐ์ฒด๊ฐ ์ ํ๋๋ ๋ฐฉํฅ์ ๋ฐ๋ผ ๋ค์๊ณผ ๊ฐ์ด 3๋จ๊ณ๋ก ๊ตฌ๋ถํ ์ ์๋ค.
<!DOCTYPE html>
<html>
<body>
<ul id="fruits">
<li id="apple">Apple</li>
<li id="banana">Banana</li>
<li id="orange">Orange</li>
</ul>
<script>
const $fruits = document.getElementById('fruits');
const $banana = document.getElementById('banana');
// #fruits ์์์ ํ์ ์์์ธ li ์์๋ฅผ ํด๋ฆญํ ๊ฒฝ์ฐ
// ์บก์ฒ๋ง ๋จ๊ณ์ ์ด๋ฒคํธ๋ฅผ ์บ์นํ๋ค.
$fruits.addEventListener('click', e => {
console.log(`์ด๋ฒคํธ ๋จ๊ณ: ${e.eventPhase}`); // 1: ์บก์ฒ๋ง ๋จ๊ณ
console.log(`์ด๋ฒคํธ ํ๊น: ${e.target}`); // [object HTMLLIElement]
console.log(`์ปค๋ฐํธ ํ๊น: ${e.currentTarget}`); // [object HTMLUListElement]
}, true);
// ํ๊น ๋จ๊ณ์ ์ด๋ฒคํธ๋ฅผ ์บ์นํ๋ค.
$banana.addEventListener('click', e => {
console.log(`์ด๋ฒคํธ ๋จ๊ณ: ${e.eventPhase}`); // 2: ํ๊น ๋จ๊ณ
console.log(`์ด๋ฒคํธ ํ๊น: ${e.target}`); // [object HTMLLIElement]
console.log(`์ปค๋ฐํธ ํ๊น: ${e.currentTarget}`); // [object HTMLLIElement]
});
// ๋ฒ๋ธ๋ง ๋จ๊ณ์ ์ด๋ฒคํธ๋ฅผ ์บ์นํ๋ค.
$fruits.addEventListener('click', e => {
console.log(`์ด๋ฒคํธ ๋จ๊ณ: ${e.eventPhase}`); // 3: ๋ฒ๋ธ๋ง ๋จ๊ณ
console.log(`์ด๋ฒคํธ ํ๊น: ${e.target}`); // [object HTMLLIElement]
console.log(`์ปค๋ฐํธ ํ๊น: ${e.currentTarget}`); // [object HTMLUListElement]
});
</script>
</body>
</html>
์์ฒ๋ผ ์ด๋ฒคํธ๋ ์ด๋ฒคํธ๋ฅผ ๋ฐ์์ํจ ํ๊ฒ์ ๋ฌผ๋ก ์์ DOM ์์์์๋ ์บ์นํ ์ ์๋ค.
<!DOCTYPE html>
<html>
<head>
<style>
#fruits {
display: flex;
list-style-type: none;
padding: 0;
}
#fruits li {
width: 100px;
cursor: pointer;
}
#fruits .active {
color: red;
text-decoration: underline;
}
</style>
</head>
<body>
<nav>
<ul id="fruits">
<li id="apple" class="active">Apple</li>
<li id="banana">Banana</li>
<li id="orange">Orange</li>
</ul>
</nav>
<div>์ ํ๋ ๋ด๋น๊ฒ์ด์
์์ดํ
: <em class="msg">apple</em></div>
<script>
const $fruits = document.getElementById('fruits');
const $msg = document.querySelector('.msg');
// ์ฌ์ฉ์ ํด๋ฆญ์ ์ํด ์ ํ๋ ๋ด๋น๊ฒ์ด์
์์ดํ
(li ์์)์ active ํด๋์ค๋ฅผ ์ถ๊ฐํ๊ณ
// ๊ทธ ์ธ์ ๋ชจ๋ ๋ด๋น๊ฒ์ด์
์์ดํ
์ active ํด๋์ค๋ฅผ ์ ๊ฑฐํ๋ค.
function activate({ target }) {
[...$fruits.children].forEach($fruit => {
$fruit.classList.toggle('active', $fruit === target);
$msg.textContent = target.id;
});
}
// ๋ชจ๋ ๋ด๋น๊ฒ์ด์
์์ดํ
(li ์์)์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋กํ๋ค.
document.getElementById('apple').onclick = activate;
document.getElementById('banana').onclick = activate;
document.getElementById('orange').onclick = activate;
</script>
</body>
</html>
์์ ์์ ๋ ๋ชจ๋ ๋ด๋น๊ฒ์ด์ ์์ดํ (li ์์)์ด ํด๋ฆญ ์ด๋ฒคํธ์ ๋ฐ์ํ๋๋ก ๋ชจ๋ ๋ด๋น๊ฒ์ด์ ์์ดํ ์ ์ด๋ฒคํธ ํธ๋ค๋ฌ์ธ activate๋ฅผ ๋ฑ๋กํ๋ค. ๋ง์ผ ๋ด๋น๊ฒ์ด์ ์์ดํ ์ด 100๊ฐ๋ผ๋ฉด 100๊ฐ์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋กํด์ผ ํ๋ฏ๋ก ์ด๋ ์ฑ๋ฅ ์ ํ์ ์์ธ์ด ๋ ๋ฟ๋๋ฌ ์ ์ง๋ณด์์๋ ๋ถ์ ํฉํ ์ฝ๋๋ฅผ ์์ฐํ๊ฒ ํ๋ค.
<!DOCTYPE html>
<html>
<head>
<style>
#fruits {
display: flex;
list-style-type: none;
padding: 0;
}
#fruits li {
width: 100px;
cursor: pointer;
}
#fruits .active {
color: red;
text-decoration: underline;
}
</style>
</head>
<body>
<nav>
<ul id="fruits">
<li id="apple" class="active">Apple</li>
<li id="banana">Banana</li>
<li id="orange">Orange</li>
</ul>
</nav>
<div>์ ํ๋ ๋ด๋น๊ฒ์ด์
์์ดํ
: <em class="msg">apple</em></div>
<script>
const $fruits = document.getElementById('fruits');
const $msg = document.querySelector('.msg');
// ์ฌ์ฉ์ ํด๋ฆญ์ ์ํด ์ ํ๋ ๋ด๋น๊ฒ์ด์
์์ดํ
(li ์์)์ active ํด๋์ค๋ฅผ ์ถ๊ฐํ๊ณ
// ๊ทธ ์ธ์ ๋ชจ๋ ๋ด๋น๊ฒ์ด์
์์ดํ
์ active ํด๋์ค๋ฅผ ์ ๊ฑฐํ๋ค.
function activate({ target }) {
// ์ด๋ฒคํธ๋ฅผ ๋ฐ์์ํจ ์์(target)๊ฐ ul#fruits์ ์์ ์์๊ฐ ์๋๋ผ๋ฉด ๋ฌด์ํ๋ค.
if (!target.matches('#fruits > li')) return;
[...$fruits.children].forEach($fruit => {
$fruit.classList.toggle('active', $fruit === target);
$msg.textContent = target.id;
});
}
// ์ด๋ฒคํธ ์์: ์์ ์์(ul#fruits)๋ ํ์ ์์์ ์ด๋ฒคํธ๋ฅผ ์บ์นํ ์ ์๋ค.
$fruits.onclick = activate;
</script>
</body>
</html>
์ด๋ฒคํธ ์์(event delegation)์ ์ฌ๋ฌ ๊ฐ์ ํ์ DOM ์์์ ๊ฐ๊ฐ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋กํ๋ ๋์ ํ๋์ ์์ DOM ์์์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋กํ๋ ๋ฐฉ๋ฒ์ด๋ค. ์ด๋ฒคํธ ์์์ ํตํด ์์ DOM ์์์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋กํ๋ฉด ์ฌ๋ฌ ๊ฐ์ ํ์ DOM ์์์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋กํ ํ์๊ฐ ์๋ค.
์ด๋ฒคํธ ์์์ ํตํด DOM ์์์์ ๋ฐ์ํ ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํ ๋ ์ฃผ์ํ ์ ์ ์์ ์์์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋กํ๊ธฐ ๋๋ฌธ์ ์ด๋ฒคํธ ํ๊น, ์ฆ ์ด๋ฒคํธ๋ฅผ ์ค์ ๋ก ๋ฐ์์ํจ DOM ์์๊ฐ ๊ฐ๋ฐ์๊ฐ ๊ธฐ๋ํ DOM ์์๊ฐ ์๋ ์๋ ์๋ค๋ ๊ฒ์ด๋ค.
Element.prototype.matches
๋ฉ์๋๋ ์ธ์๋ก ์ ๋ฌ๋ ์ ํ์์ ์ํด ํน์ ๋
ธ๋๋ฅผ ํ์ ๊ฐ๋ฅํ์ง ํ์ธํ๋ค.
function activate({ target }) {
// ์ด๋ฒคํธ๋ฅผ ๋ฐ์์ํจ ์์(target)์ด ul#fruits์ ์์ ์์๊ฐ ์๋๋ผ๋ฉด ๋ฌด์ํ๋ค.
if (!target.matches('#fruits > li')) return;
...
์ด๋ฒคํธ ๊ฐ์ฒด์ **preventDefault**
๋ฉ์๋๋ ์ด๋ฌํ DOM ์์์ ๊ธฐ๋ณธ ๋์์ ์ค๋จ์ํจ๋ค.
<!DOCTYPE html>
<html>
<body>
<a href="https://www.google.com">go</a>
<input type="checkbox">
<script>
document.querySelector('a').onclick = e => {
// a ์์์ ๊ธฐ๋ณธ ๋์์ ์ค๋จํ๋ค.
e.preventDefault();
};
document.querySelector('input[type=checkbox]').onclick = e => {
// checkbox ์์์ ๊ธฐ๋ณธ ๋์์ ์ค๋จํ๋ค.
e.preventDefault();
};
</script>
</body>
</html>
์ด๋ฒคํธ ๊ฐ์ฒด์ **stopPropagation**
๋ฉ์๋๋ ์ด๋ฒคํธ ์ ํ๋ฅผ ์ค์ง์ํจ๋ค.
<!DOCTYPE html>
<html>
<body>
<div class="container">
<button class="btn1">Button 1</button>
<button class="btn2">Button 2</button>
<button class="btn3">Button 3</button>
</div>
<script>
// ์ด๋ฒคํธ ์์. ํด๋ฆญ๋ ํ์ ๋ฒํผ ์์์ color๋ฅผ ๋ณ๊ฒฝํ๋ค.
document.querySelector('.container').onclick = ({ target }) => {
if (!target.matches('.container > button')) return;
target.style.color = 'red';
};
// .btn2 ์์๋ ์ด๋ฒคํธ๋ฅผ ์ ํํ์ง ์์ผ๋ฏ๋ก ์์ ์์์์ ์ด๋ฒคํธ๋ฅผ ์บ์นํ ์ ์๋ค.
document.querySelector('.btn2').onclick = e => {
e.stopPropagation(); // ์ด๋ฒคํธ ์ ํ ์ค๋จ
e.target.style.color = 'blue';
};
</script>
</body>
</html>
์ ์์ ๋ฅผ ์ดํด๋ณด๋ฉด ์์ DOM ์์์ธ container ์์์ ์ด๋ฒคํธ๋ฅผ ์์ํ๋ค. ๋ฐ๋ผ์ ํ์ DOM ์์์์ ๋ฐ์ํ ํด๋ฆญ ์ด๋ฒคํธ๋ฅผ ์์ DOM ์์์ธ container ์์๊ฐ ์บ์นํ์ฌ ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํ๋ค. ํ์ง๋ง ํ์ ์์์ค์์ btn2 ์์๋ ์์ฒด์ ์ผ๋ก ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํ๋ค. ์ด๋ btn2 ์์๋ ์์ ์ด ๋ฐ์์ํจ ์ด๋ฒคํธ๊ฐ ์ ํ๋๋๊ฒ์ ์ค๋จํ์ฌ ์์ ์๊ฒ ๋ฐ์ธ๋ฉ๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ง ์คํ๋๋๋ก ํ๋ค.
<!DOCTYPE html>
<html>
<body>
<button onclick="handleClick()">Click me</button>
<script>
function handleClick() {
console.log(this); // window
}
</script>
</body>
</html>
์ด๋ฒคํธ ํธ๋ค๋ฌ ์ดํธ๋ฆฌ๋ทฐํธ ๊ฐ์ผ๋ก ์ง์ ํ ๋ฌธ์์ด์ ์ฌ์ค ์๋ฌต์ ์ผ๋ก ์์ฑ๋๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ์ ๋ฌธ์ด๊ธฐ ๋๋ฌธ์ ์์ ์์ ์์ handleClick ํจ์๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ์ ์ํด ์ผ๋ฐ ํจ์๋ก ํธ์ถ๋๋ค. ์ผ๋ฐ ํจ์๋ก์ ํธ์ถ๋๋ ํจ์ ๋ด๋ถ์ this๋ ์ ์ญ ๊ฐ์ฒด๋ฅผ ๊ฐ๋ฅดํค๊ธฐ ๋๋ฌธ์ handleClick ํจ์ ๋ด๋ถ์ this๋ ์ ์ญ๊ฐ์ฒด window๋ฅผ ๊ฐ๋ฆฌํจ๋ค.
<!DOCTYPE html>
<html>
<body>
<button onclick="handleClick(this)">Click me</button>
<script>
function handleClick(button) {
console.log(button); // ์ด๋ฒคํธ๋ฅผ ๋ฐ์ธ๋ฉํ button ์์
console.log(this); // window
}
</script>
</body>
</html>
์ ์์ ์์ handleClick ํจ์์ ์ ๋ฌ๋ this๋ ์๋ฌต์ ์ผ๋ก ์์ฑ๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ ๋ด๋ถ์ this๋ค. ์ฆ, ์ด๋ฒคํธ ํธ๋ค๋ฌ ์ดํธ๋ฆฌ๋ทฐํธ ๋ฐฉ์์ ์ํด ์๋ฌต์ ์ผ๋ก ์์ฑ๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ ๋ด๋ถ์ this๋ ์ด๋ฒคํธ๋ฅผ ๋ฐ์ธ๋ฉํ DOM ์์๋ฅผ ๊ฐ๋ฆฌํจ๋ค. ์ด๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ ํ๋กํผํฐ ๋ฐฉ์๊ณผ ๋์ผํ๋ค.
addEvenetListener
๋ฉ์๋ ๋ฐฉ์์ด๋ฒคํธ ํธ๋ค๋ฌ ํ๋กํผํฐ ๋ฐฉ์๊ณผ addEventListener
๋ฉ์๋ ๋ฐฉ์ ๋ชจ๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ ๋ด๋ถ์ this๋ ์ด๋ฒคํธ๋ฅผ ๋ฐ์ธ๋ฉํ DOM ์์๋ฅผ ๊ฐ๋ฆฌํจ๋ค. ์ฆ ์ด๋ฒคํธ ํธ๋ค๋ฌ ๋ด๋ถ์ this๋ ์ด๋ฒคํธ ๊ฐ์ฒด์ currentTarget ํ๋กํผํฐ์ ๊ฐ๋ค.
<!DOCTYPE html>
<html>
<body>
<button class="btn1">0</button>
<button class="btn2">0</button>
<script>
const $button1 = document.querySelector('.btn1');
const $button2 = document.querySelector('.btn2');
// ์ด๋ฒคํธ ํธ๋ค๋ฌ ํ๋กํผํฐ ๋ฐฉ์
$button1.onclick = function (e) {
// this๋ ์ด๋ฒคํธ๋ฅผ ๋ฐ์ธ๋ฉํ DOM ์์๋ฅผ ๊ฐ๋ฆฌํจ๋ค.
console.log(this); // $button1
console.log(e.currentTarget); // $button1
console.log(this === e.currentTarget); // true
// $button1์ textContent๋ฅผ 1 ์ฆ๊ฐ์ํจ๋ค.
++this.textContent;
};
// addEventListener ๋ฉ์๋ ๋ฐฉ์
$button2.addEventListener('click', function (e) {
// this๋ ์ด๋ฒคํธ๋ฅผ ๋ฐ์ธ๋ฉํ DOM ์์๋ฅผ ๊ฐ๋ฆฌํจ๋ค.
console.log(this); // $button2
console.log(e.currentTarget); // $button2
console.log(this === e.currentTarget); // true
// $button2์ textContent๋ฅผ 1 ์ฆ๊ฐ์ํจ๋ค.
++this.textContent;
});
</script>
</body>
</html>
ํ์ดํ ํจ์๋ก ์ ์ํ ์ด๋ฒคํธ ํธ๋ค๋ฌ ๋ด๋ถ์ this๋ ์์ ์ค์ฝํ์ this๋ฅผ ๊ฐ๋ฆฌํจ๋ค. ํ์ดํ ํจ์๋ ํจ์ ์์ฒด์ this ๋ฐ์ธ๋ฉ์ ๊ฐ์ง ์๋๋ค.
<!DOCTYPE html>
<html>
<body>
<button class="btn1">0</button>
<button class="btn2">0</button>
<script>
const $button1 = document.querySelector('.btn1');
const $button2 = document.querySelector('.btn2');
// ์ด๋ฒคํธ ํธ๋ค๋ฌ ํ๋กํผํฐ ๋ฐฉ์
$button1.onclick = e => {
// ํ์ดํ ํจ์ ๋ด๋ถ์ this๋ ์์ ์ค์ฝํ์ this๋ฅผ ๊ฐ๋ฆฌํจ๋ค.
console.log(this); // window
console.log(e.currentTarget); // $button1
console.log(this === e.currentTarget); // false
// this๋ window๋ฅผ ๊ฐ๋ฆฌํค๋ฏ๋ก window.textContent์ NaN(undefined + 1)์ ํ ๋นํ๋ค.
++this.textContent;
};
// addEventListener ๋ฉ์๋ ๋ฐฉ์
$button2.addEventListener('click', e => {
// ํ์ดํ ํจ์ ๋ด๋ถ์ this๋ ์์ ์ค์ฝํ์ this๋ฅผ ๊ฐ๋ฆฌํจ๋ค.
console.log(this); // window
console.log(e.currentTarget); // $button2
console.log(this === e.currentTarget); // false
// this๋ window๋ฅผ ๊ฐ๋ฆฌํค๋ฏ๋ก window.textContent์ NaN(undefined + 1)์ ํ ๋นํ๋ค.
++this.textContent;
});
</script>
</body>
</html>
ํด๋์ค์์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฐ์ธ๋ฉํ๋ ๊ฒฝ์ฐ this์ ์ฃผ์ํด์ผ ํ๋ค. ๋ค์ ์์ ๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ ํ๋กํผํฐ ๋ฐฉ์์ ์ฌ์ฉํ๊ณ ์์ผ๋ addEventListener
๋ฉ์๋ ๋ฐฉ์์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ์ ๋์ผํ๋ค.
<!DOCTYPE html>
<html>
<body>
<button class="btn">0</button>
<script>
class App {
constructor() {
this.$button = document.querySelector('.btn');
this.count = 0;
// increase ๋ฉ์๋๋ฅผ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ก ๋ฑ๋ก
this.$button.onclick = this.increase;
}
increase() {
// ์ด๋ฒคํธ ํธ๋ค๋ฌ increase ๋ด๋ถ์ this๋ DOM ์์(this.$button)๋ฅผ ๊ฐ๋ฆฌํจ๋ค.
// ๋ฐ๋ผ์ this.$button์ this.$button.$button๊ณผ ๊ฐ๋ค.
this.$button.textContent = ++this.count;
// -> TypeError: Cannot set property 'textContent' of undefined
}
}
new App();
</script>
</body>
</html>
์ ์์ ์์ ์ด๋ฒคํธ ํธ๋ค๋ฌ ๋ด๋ถ์ this๋ ์ด๋ฒคํธ๋ฅผ ๋ฐ์ธ๋ฉํ DOM ์์๋ฅผ ๊ฐ๋ฆฌํค๊ธฐ ๋๋ฌธ์ increase ๋ฉ์๋ ๋ด๋ถ์ this๋ this.$button์ ๊ฐ๋ฆฌํจ๋ค. ๋ฐ๋ผ์ increase ๋ฉ์๋๋ฅผ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ก ๋ฐ์ธ๋ฉํ ๋ bind ๋ฉ์๋๋ฅผ ์ฌ์ฉํด this๋ฅผ ์ ๋ฌํ์ฌ increase ๋ฉ์๋ ๋ด๋ถ์ this๊ฐ ํด๋์ค๊ฐ ์์ฑํ ์ธ์คํด์ค๋ฅผ ๊ฐ๋ฆฌํค๋๋ก ํด์ผ ํ๋ค.
<!DOCTYPE html>
<html>
<body>
<button class="btn">0</button>
<script>
class App {
constructor() {
this.$button = document.querySelector('.btn');
this.count = 0;
// increase ๋ฉ์๋๋ฅผ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ก ๋ฑ๋ก
// this.$button.onclick = this.increase;
// increase ๋ฉ์๋ ๋ด๋ถ์ this๊ฐ ์ธ์คํด์ค๋ฅผ ๊ฐ๋ฆฌํค๋๋ก ํ๋ค.
this.$button.onclick = this.increase.bind(this);
}
increase() {
this.$button.textContent = ++this.count;
}
}
new App();
</script>
</body>
</html>
๋๋ ํด๋์ค ํ๋์ ํ ๋นํ ํ์ดํ ํจ์๋ฅผ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ก ๋ฑ๋กํ์ฌ ์ด๋ฒคํธ ํธ๋ค๋ฌ ๋ด๋ถ์ this๊ฐ ์ธ์คํด์ค๋ฅผ ๊ฐ๋ฆฌํค๋๋ก ํ ์๋ ์๋ค. ๋ค๋ง ์ด๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ increase๋ ํ๋กํ ํ์ ๋ฉ์๋๊ฐ ์๋ ์ธ์คํด์ค ๋ฉ์๋๊ฐ ๋๋ค.
<!DOCTYPE html>
<html>
<body>
<button class="btn">0</button>
<script>
class App {
constructor() {
this.$button = document.querySelector('.btn');
this.count = 0;
// ํ์ดํ ํจ์์ธ increase๋ฅผ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ก ๋ฑ๋ก
this.$button.onclick = this.increase;
}
// ํด๋์ค ํ๋ ์ ์
// increase๋ ์ธ์คํด์ค ๋ฉ์๋์ด๋ฉฐ ๋ด๋ถ์ this๋ ์ธ์คํด์ค๋ฅผ ๊ฐ๋ฆฌํจ๋ค.
increase = () => this.$button.textContent = ++this.count;
}
new App();
</script>
</body>
</html>
์ด๋ฒคํธ ํธ๋ค๋ฌ ์ดํธ๋ฆฌ๋ทฐํธ ๋ฐฉ์์ ํจ์ ํธ์ถ๋ฌธ์ ์ฌ์ฉํ ์ ์๊ธฐ ๋๋ฌธ์ ์ธ์๋ฅผ ์ ๋ฌํ ์ ์์ง๋ง ์ด๋ฒคํธ ํธ๋ค๋ฌ ํ๋กํผํฐ ๋ฐฉ์๊ณผ addEventListener ๋ฉ์๋ ๋ฐฉ์์ ๊ฒฝ์ฐ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ธ๋ผ์ฐ์ ๊ฐ ํธ์ถํ๊ธฐ ๋๋ฌธ์ ํจ์ ํธ์ถ๋ฌธ์ด ์๋ ํจ์ ์์ฒด๋ฅผ ๋ฑ๋กํด์ผ ํ๋ค. ๋ฐ๋ผ์ ์ธ์๋ฅผ ์ ๋ฌํ๋ ค๋ฉด ์ด๋ฒคํธ ํธ๋ค๋ฌ ๋ด๋ถ์์ ํจ์๋ฅผ ํธ์ถํ๋ฉด์ ์ธ์๋ฅผ ์ ๋ฌํด์ผ ํ๋ค.
<!DOCTYPE html>
<html>
<body>
<label>User name <input type='text'></label>
<em class="message"></em>
<script>
const MIN_USER_NAME_LENGTH = 5; // ์ด๋ฆ ์ต์ ๊ธธ์ด
const $input = document.querySelector('input[type=text]');
const $msg = document.querySelector('.message');
const checkUserNameLength = min => {
$msg.textContent
= $input.value.length < min ? `์ด๋ฆ์ ${min}์ ์ด์ ์
๋ ฅํด ์ฃผ์ธ์` : '';
};
// ์ด๋ฒคํธ ํธ๋ค๋ฌ ๋ด๋ถ์์ ํจ์๋ฅผ ํธ์ถํ๋ฉด์ ์ธ์๋ฅผ ์ ๋ฌํ๋ค.
$input.onblur = () => {
checkUserNameLength(MIN_USER_NAME_LENGTH);
};
</script>
</body>
</html>
๋๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฐํํ๋ ํจ์๋ฅผ ํธ์ถํ๋ฉด์ ์ธ์๋ฅผ ์ ๋ฌํ ์๋ ์๋ค.
<!DOCTYPE html>
<html>
<body>
<label>User name <input type='text'></label>
<em class="message"></em>
<script>
const MIN_USER_NAME_LENGTH = 5; // ์ด๋ฆ ์ต์ ๊ธธ์ด
const $input = document.querySelector('input[type=text]');
const $msg = document.querySelector('.message');
// ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฐํํ๋ ํจ์
const checkUserNameLength = min => e => {
$msg.textContent
= $input.value.length < min ? `์ด๋ฆ์ ${min}์ ์ด์ ์
๋ ฅํด ์ฃผ์ธ์` : '';
};
// ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฐํํ๋ ํจ์๋ฅผ ํธ์ถํ๋ฉด์ ์ธ์๋ฅผ ์ ๋ฌํ๋ค.
$input.onblur = checkUserNameLength(MIN_USER_NAME_LENGTH);
</script>
</body>
</html>
checkUserNameLength
ํจ์๋ ํจ์๋ฅผ ๋ฐํํ๋ค. ๋ฐ๋ผ์ $input.onblur์๋ ๊ฒฐ๊ตญ checkUserNameLength
ํจ์๊ฐ ๋ฐํํ๋ ํจ์๊ฐ ๋ฐ์ธ๋ฉ๋๋ค.
์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด ์๋ฌต์ ์ผ๋ก ์์ฑ๋๋ ์ด๋ฒคํธ ๊ฐ์ฒด๋ ๋ฐ์ํ ์ด๋ฒคํธ์ ์ข ๋ฅ์ ๋ฐ๋ผ ํ์ ์ด ๊ฒฐ์ ๋๋ค. ํ์ง๋ง Event, UIEvent, MouseEvent ๊ฐ์ ์ด๋ฒคํธ ์์ฑ์ ํจ์๋ฅผ ํธ์ถํ์ฌ ๋ช ์์ ์ผ๋ก ์์ฑํ ์ด๋ฒคํธ ๊ฐ์ฒด๋ ์์์ ์ด๋ฒคํธ ํ์ ์ ์ง์ ํ ์ ์๋ค. ์ด์ฒ๋ผ ๊ฐ๋ฐ์์ ์๋๋ก ์์ฑ๋ ์ด๋ฒคํธ๋ฅผ ์ปค์คํ ์ด๋ฒคํธ๋ผ๊ณ ํ๋ค.
์ด๋ฒคํธ ์์ฑ์ ํจ์๋ ์ฒซ ๋ฒ์งธ ์ธ์๋ก ์ด๋ฒคํธ ํ์ ์ ๋ํ๋ด๋ ๋ฌธ์์ด์ ์ ๋ฌ๋ฐ๋๋ค. ์ด๋ ์ด๋ฒคํธ ํ์ ์ ๋ํ๋ด๋ ๋ฌธ์์ด์ ๊ธฐ์กด ์ด๋ฒคํธํ์ ์ ์ฌ์ฉํ๊ฑฐ๋ ์์์ ๋ฌธ์์ด์ ์ฌ์ฉํ๋ค.
// KeyboardEvent ์์ฑ์ ํจ์๋ก keyup ์ด๋ฒคํธ ํ์
์ ์ปค์คํ
์ด๋ฒคํธ ๊ฐ์ฒด๋ฅผ ์์ฑ
const keyboardEvent = new KeyboardEvent('keyup');
console.log(keyboardEvent.type); // keyup
// CustomEvent ์์ฑ์ ํจ์๋ก foo ์ด๋ฒคํธ ํ์
์ ์ปค์คํ
์ด๋ฒคํธ ๊ฐ์ฒด๋ฅผ ์์ฑ
const customEvent = new CustomEvent('foo');
console.log(customEvent.type); // foo
์์ฑ๋ ์ปค์คํ ์ด๋ฒคํธ ๊ฐ์ฒด๋ ๋ฒ๋ธ๋ง๋์ง ์์ผ๋ฉฐ preventDefault ๋ฉ์๋๋ก ์ทจ์ํ ์๋ ์๋ค. ์ฆ, ์ปค์คํ ์ด๋ฒคํธ ๊ฐ์ฒด๋ bubbles์ cancelable ํ๋กํผํฐ ๊ฐ์ด false๋ก ๊ธฐ๋ณธ ์ค์ ๋๋ค.
// MouseEvent ์์ฑ์ ํจ์๋ก click ์ด๋ฒคํธ ํ์
์ ์ปค์คํ
์ด๋ฒคํธ ๊ฐ์ฒด๋ฅผ ์์ฑ
const customEvent = new MouseEvent('click');
console.log(customEvent.type); // click
console.log(customEvent.bubbles); // false
console.log(customEvent.cancelable); // false
์ปค์คํ ์ด๋ฒคํธ ๊ฐ์ฒด์ bubbles ๋๋ cancelable ํ๋กํผํฐ๋ฅผ true๋ก ์ค์ ํ๋ ค๋ฉด ์ด๋ฒคํธ ์์ฑ์ ํจ์์ ๋ ๋ฒ์งธ ์ธ์๋ก bubbles ๋๋ cancelabla ํ๋กํผํฐ๋ฅผ ๊ฐ๋ ๊ฐ์ฒด๋ฅผ ์ ๋ฌํ๋ค.
// MouseEvent ์์ฑ์ ํจ์๋ก click ์ด๋ฒคํธ ํ์
์ ์ปค์คํ
์ด๋ฒคํธ ๊ฐ์ฒด๋ฅผ ์์ฑ
const customEvent = new MouseEvent('click', {
bubbles: true,
cancelable: true
});
console.log(customEvent.bubbles); // true
console.log(customEvent.cancelable); // true
์ปค์คํ ์ด๋ฒคํธ ๊ฐ์ฒด์๋ bubbles ๋๋ cancelable ํ๋กํผํฐ๋ฟ๋ง ์๋๋ผ ์ด๋ฒคํธ ํ์ ์ ๋ฐ๋ผ ๊ฐ์ง๋ ์ด๋ฒคํธ ๊ณ ์ ์ ํ๋กํผํฐ ๊ฐ์ ์ง์ ํ ์ ์๋ค. ์๋ฅผ ๋ค์ด, MouseEvent ์์ฑ์ ํจ์๋ก ์์ฑํ ๋ง์ฐ์ค ์ด๋ฒคํธ ๊ฐ์ฒด๋ ๋ง์ฐ์ค ํฌ์ธํฐ์ ์ขํ ์ ๋ณด๋ฅผ ๋ํ๋ด๋ ๋ง์ฐ์ค ์ด๋ฒคํธ ๊ฐ์ฒด ๊ณ ์ ์ ํ๋กํผํฐ screenX /screenY, clientX/clientY, pageX/pageY, offsetX/offsetY์ ๋ฒํผ ์ ๋ณด๋ฅผ ๋ํ๋ด๋ ํ๋กํผํฐ altKey, ctrlKey, shiftKey, button์ ๊ฐ๋๋ค. ์ด๋ฌํ ์ด๋ฒคํธ ๊ฐ์ฒด ๊ณ ์ ์ ํ๋กํผํฐ ๊ฐ์ ์ง์ ํ๋ ค๋ฉด ๋ค์๊ณผ ๊ฐ์ด ์ด๋ฒคํธ ์์ฑ์ ํจ์์ ๋ ๋ฒ์งธ ์ธ์๋ก ํ๋กํผํฐ๋ฅผ ์ ๋ฌํ๋ค.
// MouseEvent ์์ฑ์ ํจ์๋ก click ์ด๋ฒคํธ ํ์
์ ์ปค์คํ
์ด๋ฒคํธ ๊ฐ์ฒด๋ฅผ ์์ฑ
const mouseEvent = new MouseEvent('click', {
bubbles: true,
cancelable: true,
clientX: 50,
clientY: 100
});
console.log(mouseEvent.clientX); // 50
console.log(mouseEvent.clientY); // 100
// KeyboardEvent ์์ฑ์ ํจ์๋ก keyup ์ด๋ฒคํธ ํ์
์ ์ปค์คํ
์ด๋ฒคํธ ๊ฐ์ฒด๋ฅผ ์์ฑ
const keyboardEvent = new KeyboardEvent('keyup', { key: 'Enter' });
console.log(keyboardEvent.key); // Enter
์ด๋ฒคํธ ์์ฑ์ ํจ์๋ก ์์ฑํ ์ปค์คํ ์ด๋ฒคํธ๋ isTrusted ํ๋กํผํฐ ๊ฐ์ด ์ธ์ ๋ false๋ค. ์ปค์คํ ์ด๋ฒคํธ๊ฐ ์๋ ์ฌ์ฉ์์ ํ์์ ์ํด ๋ฐ์ํ ์ด๋ฒคํธ ๊ฐ์ฒด์ isTrusted ํ๋กํผํฐ ๊ฐ์ ์ธ์ ๋ true๋ค.
// InputEvent ์์ฑ์ ํจ์๋ก foo ์ด๋ฒคํธ ํ์
์ ์ปค์คํ
์ด๋ฒคํธ ๊ฐ์ฒด๋ฅผ ์์ฑ
const customEvent = new InputEvent('foo');
console.log(customEvent.isTrusted); // false
์์ฑ๋ ์ปค์คํ
์ด๋ฒคํธ๋ **dispatchEvent**
๋ฉ์๋๋ก ๋์คํจ์น(dispatch)(์ด๋ฒคํธ๋ฅผ ๋ฐ์์ํค๋ ํ์)๋ฅผ ํ ์ ์๋ค. **dispatchEvent**
๋ฉ์๋์ ์ด๋ฒคํธ ๊ฐ์ฒด๋ฅผ ์ธ์๋ก ์ ๋ฌํ๋ฉด์ ํธ์ถํ๋ฉด ์ธ์๋ก ์ ๋ฌํ ์ด๋ฒคํธ ํ์
์ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ค.
<!DOCTYPE html>
<html>
<body>
<button class="btn">Click me</button>
<script>
const $button = document.querySelector('.btn');
// ๋ฒํผ ์์์ click ์ปค์คํ
์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋ก
// ์ปค์คํ
์ด๋ฒคํธ๋ฅผ ๋์คํจ์นํ๊ธฐ ์ด์ ์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋กํด์ผ ํ๋ค.
$button.addEventListener('click', e => {
console.log(e); // MouseEvent {isTrusted: false, screenX: 0, ...}
alert(`${e} Clicked!`);
});
// ์ปค์คํ
์ด๋ฒคํธ ์์ฑ
const customEvent = new MouseEvent('click');
// ์ปค์คํ
์ด๋ฒคํธ ๋์คํจ์น(๋๊ธฐ ์ฒ๋ฆฌ). click ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ค.
$button.dispatchEvent(customEvent);
</script>
</body>
</html>
์ผ๋ฐ์ ์ผ๋ก ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ ๋น๋๊ธฐ(asynchronous) ์ฒ๋ฆฌ ๋ฐฉ์์ผ๋ก ๋์ํ์ง๋ง **dispatchEvent**
๋ฉ์๋๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋๊ธฐ(synchronous)๋ฐฉ์์ผ๋ก ์ฒ๋ฆฌํ๋ค. ๋ค์ ๋งํด **dispatchEvent**
๋ฉ์๋๋ฅผ ํธ์ถํ๋ฉด ์ปค์คํ
์ด๋ฒคํธ์ ๋ฐ์ธ๋ฉ๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ์ง์ ํธ์ถํ๋ ๊ฒ๊ณผ ๊ฐ๋ค. ๋ฐ๋ผ์ dispatchEvent ๋ฉ์๋๋ก ์ด๋ฒคํธ๋ฅผ ๋์คํจ์น ํ๊ธฐ ์ด์ ์ ์ปค์คํ
์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํ ์ด๋ฒคํธ ํธ๋ค๋ฌ์ ๋ฑ๋กํด์ผ ํ๋ค.
// CustomEvent ์์ฑ์ ํจ์๋ก foo ์ด๋ฒคํธ ํ์
์ ์ปค์คํ
์ด๋ฒคํธ ๊ฐ์ฒด๋ฅผ ์์ฑ
const customEvent = new CustomEvent('foo');
console.log(customEvent.type); // foo
์ด๋ CustonEvent ์ด๋ฒคํธ ์์ฑ์ ํจ์์๋ ๋ ๋ฒ์งธ ์ธ์๋ก ์ด๋ฒคํธ์ ํจ๊ป ์ ๋ฌํ๊ณ ์ถ์ ์ ๋ณด๋ฅผ ๋ด์ detail ํ๋กํผํฐ๋ฅผ ํฌํจํ๋ ๊ฐ์ฒด๋ฅผ ์ ๋ฌํ ์ ์๋ค. ์ด ์ ๋ณด๋ ์ด๋ฒคํธ ๊ฐ์ฒด์ detail ํ๋กํผํฐ์ ๋ด๊ฒจ ์ ๋ฌ๋๋ค.
<!DOCTYPE html>
<html>
<body>
<button class="btn">Click me</button>
<script>
const $button = document.querySelector('.btn');
// ๋ฒํผ ์์์ foo ์ปค์คํ
์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋ก
// ์ปค์คํ
์ด๋ฒคํธ๋ฅผ ๋์คํจ์นํ๊ธฐ ์ด์ ์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋กํด์ผ ํ๋ค.
$button.addEventListener('foo', e => {
// e.detail์๋ CustomEvent ํจ์์ ๋ ๋ฒ์งธ ์ธ์๋ก ์ ๋ฌํ ์ ๋ณด๊ฐ ๋ด๊ฒจ ์๋ค.
alert(e.detail.message);
});
// CustomEvent ์์ฑ์ ํจ์๋ก foo ์ด๋ฒคํธ ํ์
์ ์ปค์คํ
์ด๋ฒคํธ ๊ฐ์ฒด๋ฅผ ์์ฑ
const customEvent = new CustomEvent('foo', {
detail: { message: 'Hello' } // ์ด๋ฒคํธ์ ํจ๊ป ์ ๋ฌํ๊ณ ์ถ์ ์ ๋ณด
});
// ์ปค์คํ
์ด๋ฒคํธ ๋์คํจ์น
$button.dispatchEvent(customEvent);
</script>
</body>
</html>
๊ธฐ์กด ์ด๋ฒคํธ ํ์ ์ด ์๋ ์์์ ์ด๋ฒคํธ ํ์ ์ ์ง์ ํ์ฌ ์ปค์คํ ์ด๋ฒคํธ ๊ฐ์ฒด๋ฅผ ์์ฑํ ๊ฒฝ์ฐ ๋ฐ๋์ addEventListener ๋ฉ์๋ ๋ฐฉ์์ผ๋ก ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋กํด์ผ ํ๋ค. ์ด๋ฒคํธ ํธ๋ค๋ฌ ์ดํธ๋ฆฌ๋ทฐํธ/ํ๋กํผํฐ๋ฐฉ์์ ์ฌ์ฉํ ์ ์๋ ์ด์ ๋ โon + ์ด๋ฒคํธ ํ์ โ์ผ๋ก ์ด๋ฃจ์ด์ง ์ด๋ฒคํธ ํธ๋ค๋ฌ ์ดํธ๋ฆฌ๋ทฐํธ/ํ๋กํผํฐ๊ฐ ์์ ๋ ธ๋์ ์กด์ฌํ์ง ์๊ธฐ ๋๋ฌธ์ด๋ค.