ํฐ์คํ ๋ฆฌ ๋ทฐ
[JavaScript] ์ด๋ฒคํธ
๊ฐ๋ฐ๊ฐ๊ตด๐ธ 2022. 8. 13. 22:32์ด๋ฒคํธ ๋๋ฆฌ๋ธ ํ๋ก๊ทธ๋๋ฐ
๋ธ๋ผ์ฐ์ ๋ ์ฒ๋ฆฌํด์ผ ํ ํน์ ์ฌ๊ฑด(ํด๋ฆญ, ํค๋ณด๋ ์ ๋ ฅ, ๋ง์ฐ์ค ์ด๋ ๋ฑ)์ด ๋ฐ์ํ๋ฉด ์ด๋ฅผ ๊ฐ์งํ์ฌ ์ด๋ฒคํธ๋ฅผ ๋ฐ์์ํต๋๋ค.
์ด๋, ์ ํ๋ฆฌ์ผ์ด์ ์ด ํน์ ํ์ ์ ์ด๋ฒคํธ์ ๋ํด ๋ฐ์ํ์ฌ ์ด๋ค ์ผ์ ํ๊ณ ์ถ๋ค๋ฉด ํด๋นํ๋ ํ์ ์ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ์ ๋ ํธ์ถ๋ ํจ์๋ฅผ ๋ธ๋ผ์ฐ์ ์๊ฒ ์๋ ค ํธ์ถ์ ์์ํฉ๋๋ค.
- ์ด๋ฒคํธ ํธ๋ค๋ฌ : ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ์ ๋ ํธ์ถ๋ ํจ์
- ์ด๋ฒคํธ ํธ๋ค๋ฌ ๋ฑ๋ก : ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ์ ๋ ๋ธ๋ผ์ฐ์ ์๊ฒ ์ด๋ฒคํธ ํธ๋ค๋ฌ์ ํธ์ถ์ ์์ํ๋ ๊ฒ
<!DOCTYPE html>
<html>
<body>
<button>Click me!</button>
<script>
const $button = document.querySelector('button');
// ์ฌ์ฉ์๊ฐ ๋ฒํผ์ ํด๋ฆญํ๋ฉด ํจ์๋ฅผ ํธ์ถํ๋๋ก ์์ฒญ
$button.onclick = () => { alert('button click'); };
</script>
</body>
</html>
์ ์์ ์ ๊ฐ์ด ๋ธ๋ผ์ฐ์ ๋ ์ฌ์ฉ์์ ์ฌ๊ฑด(ํด๋ฆญ)์ ๊ฐ์งํ์ฌ ์ด๋ฒคํธ๋ฅผ ๋ฐ์์ํค๊ณ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ํธ์ถํ๋๋ก ์ด๋ฒคํธ ํธ๋ค๋ฌ ๋ฑ๋ก์ ํ ์ ์์ต๋๋ค. ์ฆ, ์ด๋ฒคํธ์ ๊ทธ์ ๋์ํ๋ ํจ์(์ด๋ฒคํธ ํธ๋ค๋ฌ)๋ฅผ ํตํด ์ฌ์ฉ์์ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ํธ์์ฉ์ ํ ์ ์์ผ๋ฉฐ, ์ด์ ๊ฐ์ด ํ๋ก๊ทธ๋จ์ ํ๋ฆ์ ์ด๋ฒคํธ ์ค์ฌ์ผ๋ก ์ ์ดํ๋ ํ๋ก๊ทธ๋๋ฐ ๋ฐฉ์์ ์ด๋ฒคํธ ๋๋ฆฌ๋ธ ํ๋ก๊ทธ๋๋ฐ์ด๋ผ ํฉ๋๋ค.
์ด๋ฒคํธ ํ์
์ด๋ฒคํธ ํ์ ์ ์ด๋ฒคํธ์ ์ข ๋ฅ๋ฅผ ๋ํ๋ด๋ ๋ฌธ์์ด์ ๋๋ค. ์ฝ 200์ฌ ๊ฐ์ง๊ฐ ์๋ ์ด๋ฒคํธ ํ์ ์ค ์ฌ์ฉ ๋น๋๊ฐ ๋์ ์ด๋ฒคํธ๋ค์ ๋ํด ์ดํด๋ณด๊ฒ ์ต๋๋ค.
๋ง์ฐ์ค ์ด๋ฒคํธ
์ด๋ฒคํธ ํ์ | ์ด๋ฒคํธ ๋ฐ์ ์์ |
click | ๋ง์ฐ์ค ๋ฒํผ์ ํด๋ฆญํ์ ๋ |
dblclick | ๋ง์ฐ์ค ๋ฒํผ์ ๋๋ธ ํด๋ฆญํ์ ๋ |
mousedown | ๋ง์ฐ์ค ๋ฒํผ์ ๋๋ ์ ๋ |
mouseup | ๋๋ฅด๊ณ ์๋ ๋ง์ฐ์ค ๋ฒํผ์ ๋์์ ๋ |
mousemove | ๋ง์ฐ์ค ์ปค์๋ฅผ ์์ง์์ ๋ |
mouseenter | ๋ง์ฐ์ค ์ปค์๋ฅผ HTML ์์ ์์ผ๋ก ์ด๋ํ์ ๋(๋ฒ๋ธ๋งX) |
mouseover | ๋ง์ฐ์ค ์ปค์๋ฅผ HTML ์์ ์์ผ๋ก ์ด๋ํ์ ๋(๋ฒ๋ธ๋งO) |
mouseleave | ๋ง์ฐ์ค ์ปค์๋ฅผ HTML ์์ ๋ฐ์ผ๋ก ์ด๋ํ์ ๋(๋ฒ๋ธ๋งX) |
mosueout | ๋ง์ฐ์ค ์ปค์๋ฅผ HTML ์์ ๋ฐ์ผ๋ก ์ด๋ํ์ ๋(๋ฒ๋ธ๋งO) |
* ๋ฒ๋ธ๋ง : ํ์์์์์ ์์์์๋ก์ ์ด๋ฒคํธ ์ ํ ๋ฐฉ์์ผ๋ก HTML ๊ตฌ์กฐ์ ์์์์์ ๋ฐ์ํ ์ด๋ฒคํธ๊ฐ ์์ ๋ถ๋ชจ์์์๊น์ง ์ํฅ์ ๋ฏธ์น๋ ๊ฒ
ํค๋ณด๋ ์ด๋ฒคํธ
์ด๋ฒคํธ ํ์ | ์ด๋ฒคํธ ๋ฐ์ ์์ |
keydown | ๋ชจ๋ ํค๋ฅผ ๋๋ ์ ๋ ๋ฐ์ |
keypress | ๋ฌธ์ ํค๋ฅผ ๋๋ ์ ๋ ์ฐ์์ ์ผ๋ก ๋ฐ์ |
keyup | ๋๋ฅด๊ณ ์๋ ํค๋ฅผ ๋์์ ๋ ํ ๋ฒ๋ง ๋ฐ์ |
ํฌ์ปค์ค ์ด๋ฒคํธ
์ด๋ฒคํธ ํ์ | ์ด๋ฒคํธ ๋ฐ์ ์์ |
focus | HTML ์์๊ฐ ํฌ๊ฑฐ์ค๋ฅผ ๋ฐ์์ ๋(๋ฒ๋ธ๋งX) |
blur | HTML ์์๊ฐ ํฌ๊ฑฐ์ค๋ฅผ ์์์ ๋(๋ฒ๋ธ๋งX) |
focusin | HTML ์์๊ฐ ํฌ๊ฑฐ์ค๋ฅผ ๋ฐ์์ ๋(๋ฒ๋ธ๋งO) |
focusout | HTML ์์๊ฐ ํฌ๊ฑฐ์ค๋ฅผ ์์์ ๋(๋ฒ๋ธ๋งX) |
*focusin, focusout ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ addEventLisner ๋ฉ์๋ ๋ฐฉ์์ ์ด์ฉํด ๋ฑ๋กํด์ผ ํจ
ํผ ์ด๋ฒคํธ
์ด๋ฒคํธ ํ์ | ์ด๋ฒคํธ ๋ฐ์ ์์ |
submit | form ์์ ๋ด์ input, select ์
๋ ฅ ํ๋(textarea ์ ์ธ)์์ ์ํฐ ํค๋ฅผ ๋๋ ์ ๋ form ์์ ๋ด์ submit ๋ฒํผ์ ํด๋ฆญํ์ ๋ |
reset | form ์์ ๋ด์ reset ๋ฒํผ์ ํด๋ฆญํ์ ๋(์ต๊ทผ์ ์ฌ์ฉX) |
๊ฐ ๋ณ๊ฒฝ ์ด๋ฒคํธ
์ด๋ฒคํธ ํ์ | ์ด๋ฒคํธ ๋ฐ์ ์์ |
input | input, select, textarea ์์์ ๊ฐ์ด ์ ๋ ฅ๋์์ ๋ |
change | input, select, teatarea ์์์ ๊ฐ์ด ๋ณ๊ฒฝ๋์์ ๋ |
readystatechange | HTML ๋ฌธ์์ ๋ก๋์ ํ์ฑ์ด ์ํ๋ฅผ ๋ํ๋ด๋ document.readyState ํ๋กํผํฐ ๊ฐ('loading', 'interactive', 'complete')์ด ๋ณ๊ฒฝ๋ ๋ |
DOM ๋ฎคํ ์ด์ ์ด๋ฒคํธ
์ด๋ฒคํธ ํ์ | ์ด๋ฒคํธ ๋ฐ์ ์์ |
DOMContentLoaded | HTML ๋ฌธ์์ ๋ก๋์ ํ์ฑ์ด ์๋ฃ๋์ด DOM ์์์ ์๋ฃ๋์์ ๋ |
๋ทฐ ์ด๋ฒคํธ
์ด๋ฒคํธ ํ์ | ์ด๋ฒคํธ ๋ฐ์ ์์ |
resize | ๋ธ๋ผ์ฐ์ ์๋์ฐ์ ํฌ๊ธฐ๋ฅผ ๋ฆฌ์ฌ์ด์ฆํ ๋ ์ฐ์์ ์ผ๋ก ๋ฐ์ |
scroll | ์นํ์ด์ง(document) ๋๋ HTML ์์๋ฅผ ์คํฌ๋กคํ ๋ ์ฐ์์ ์ผ๋ก ๋ฐ์ |
๋ฆฌ์์ค ์ด๋ฒคํธ
์ด๋ฒคํธ ํ์ | ์ด๋ฒคํธ ๋ฐ์ ์์ |
load | DOMContentLoaded ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ ํ, ๋ชจ๋ ๋ฆฌ์์ค์ ๋ก๋ฉ์ด ์๋ฃ๋์์ ๋ |
unload | ๋ฆฌ์์ค๊ฐ ์ธ๋ก๋๋ ๋ |
abort | ๋ฆฌ์์ค ๋ก๋ฉ์ด ์ค๋จ๋์์ ๋ |
error | ๋ฆฌ์์ค ๋ก๋ฉ์ด ์คํจํ์ ๋ |
์ด๋ฒคํธ ํธ๋ค๋ฌ ๋ฑ๋ก
์ด๋ฒคํธ๊ฐ ๋ฐ์ํ์ ๋ ๋ธ๋ผ์ฐ์ ์๊ฒ ์ด๋ฒคํธ ํธ๋ค๋ฌ์ ํธ์ถ์ ์์ํ๋ ๊ฒ์ ์ด๋ฒคํธ ํธ๋ค๋ฌ ๋ฑ๋ก์ด๋ผ ํ๋ฉฐ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋กํ๋ ๋ฐฉ๋ฒ์ 3๊ฐ์ง๊ฐ ์์ต๋๋ค.
์ด๋ฒคํธ ํธ๋ค๋ฌ ์ดํธ๋ฆฌ๋ทฐํธ ๋ฐฉ์
HTML ์์์ ์ดํธ๋ฆฌ๋ทฐํธ ์ค์๋ ์ด๋ฒคํธ์ ๋์ํ๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ ์ดํธ๋ฆฌ๋ทฐํธ๊ฐ ์์ต๋๋ค.
- ์ด๋ฒคํธ ํธ๋ค๋ฌ ์ดํธ๋ฆฌ๋ทฐํธ์ ์ด๋ฆ์ on ์ ๋์ฌ์ ์ด๋ฒคํธ์ ์ข ๋ฅ๋ฅผ ๋ํ๋ด๋ ์ด๋ฒคํธ ํ์ (onclick)์ผ๋ก ์ด๋ฃจ์ด์ ธ ์์
- ์ด๋ฒคํธ ํธ๋ค๋ฌ ์ดํธ๋ฆฌ๋ทฐํธ์ ๊ฐ์ผ๋ก ํจ์ ํธ์ถ๋ฌธ ๋ฑ์ ๋ฌธ์ ํ ๋นํ๋ฉด ์ด๋ฒคํธ ํธ๋ค๋ฌ๊ฐ ๋ฑ๋ก๋จ
<!DOCTYPE html>
<html>
<body>
<button onclick="sayHi('Lee')">Click me!</button>
<script>
function sayHi(name) {
console.log(`Hi! ${name}.`);
}
</script>
</body>
</html>
์ด๋ฒคํธ ํธ๋ค๋ฌ ์ดํธ๋ฆฌ๋ทฐํธ ๊ฐ์ผ๋ก ํ ๋นํ ๋ฌธ์์ด์ ์๋ฌต์ ์ผ๋ก ์์ฑ๋๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ์ ํจ์ ๋ชธ์ฒด์ ๋๋ค. ๋ฐ๋ผ์ ํจ์ ์ฐธ์กฐ๊ฐ ์๋ ํจ์ ํธ์ถ๋ฌธ ๋ฑ์ ๋ฌธ์ ํ ๋นํ์ฌ๋ ์๋์ ๊ฐ์ด onclick="sayHi('Lee')" ์ดํธ๋ฆฌ๋ทฐํธ๋ ํ์ฑ๋์ด ํจ์๋ฅผ ์๋ฌต์ ์ผ๋ก ์์ฑํ๊ณ ์ด๋ฅผ onclick ์ด๋ฒคํธ ํธ๋ค๋ฌ ํ๋กํผํฐ์ ํ ๋นํฉ๋๋ค.
function onclick(event) {
sayHi('Lee');
}
์ด๋ฒคํธ ํธ๋ค๋ฌ ํ๋กํผํฐ ๋ฐฉ์
window ๊ฐ์ฒด์ Document, HTMLElement ํ์ ์ DOM ๋ ธ๋ ๊ฐ์ฒด๋ ์ด๋ฒคํธ์ ๋์ํ๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ ํ๋กํผํฐ๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๋ค.
- ์ด๋ฒคํธ ํธ๋ค๋ฌ ํ๋กํผํฐ ํค๋ on ์ ๋์ฌ์ ์ด๋ฒคํธ์ ์ข ๋ฅ๋ฅผ ๋ํ๋ด๋ ์ด๋ฒคํธ ํ์ (onclick)์ผ๋ก ์ด๋ฃจ์ด์ ธ ์์
- ์ด๋ฒคํธ ํธ๋ค๋ฌ ํ๋กํผํฐ์ ํจ์๋ฅผ ๋ฐ์ธ๋ฉํ๋ฉด ์ด๋ฒคํธ ํธ๋ค๋ฌ๊ฐ ๋ฑ๋ก๋จ
<!DOCTYPE html>
<html>
<body>
<button>Click me!</button>
<script>
const $button = document.querySelector('button');
// ์ด๋ฒคํธ ํธ๋ค๋ฌ ํ๋กํผํฐ์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฐ์ธ๋ฉ
$button.onclick = function () {
console.log('button click');
};
</script>
</body>
</html>
์ด์ฒ๋ผ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋กํ๊ธฐ ์ํด์๋ ์ด๋ฒคํธ๋ฅผ ๋ฐ์์ํฌ ๊ฐ์ฒด์ธ ์ด๋ฒคํธ ํ๊น๊ณผ ์ด๋ฒคํธ์ ์ข ๋ฅ๋ฅผ ๋ํ๋ด๋ ๋ฌธ์์ด์ธ ์ด๋ฒคํธ ํ์ ๊ทธ๋ฆฌ๊ณ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ์ง์ ํ ํ์๊ฐ ์์ต๋๋ค.
addEventListener ๋ฉ์๋ ๋ฐฉ์
DOM level2 ์์ ๋์ ๋ EventTarget.prototype.addEventListener ๋ฉ์๋๋ฅผ ์ฌ์ฉํด ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋กํ ์ ์์ต๋๋ค.
- ์ฒซ ๋ฒ์งธ ๋งค๊ฐ๋ณ์ : ์ด๋ฒคํธ ์ข ๋ฅ๋ฅผ ๋ํ๋ด๋ ๋ฌธ์์ด์ ์ ๋ฌ(on ์ ๋์ฌ X)
- ๋ ๋ฒ์งธ ๋งค๊ฐ๋ณ์ : ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ์ ๋ฌ
- ๋ง์ง๋ง ๋งค๊ฐ ๋ณ์ : ์ด๋ฒคํธ๋ฅผ ์บ์นํ ์ด๋ฒคํธ ์ ํ ๋จ๊ณ(์บก์ณ๋ง|๋ฒ๋ธ๋ง)๋ฅผ ์ง์
<!DOCTYPE html>
<html>
<body>
<button>Click me!</button>
<script>
const $button = document.querySelector('button');
// addEventListener ๋ฉ์๋๋ ๋์ผํ ์์์์ ๋ฐ์ํ ๋์ผํ ์ด๋ฒคํธ์ ๋ํด
// ํ๋ ์ด์์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋กํ ์ ์๋ค.
$button.addEventListener('click', function () {
console.log('[1]button click');
});
$button.addEventListener('click', function () {
console.log('[2]button click');
});
const handleClick = () => console.log('button click');
// ์ฐธ์กฐ๊ฐ ๋์ผํ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ์ค๋ณต ๋ฑ๋กํ๋ฉด ํ๋์ ํธ๋ค๋ฌ๋ง ๋ฑ๋ก๋๋ค.
$button.addEventListener('click', handleClick);
$button.addEventListener('click', handleClick);
</script>
</body>
</html>
์ ์์ ์ฒ๋ผ ๋์ผํ HTML ์์์์ ๋ฐ์ํ ๋์ผํ ์ด๋ฒคํธ์ ๋ํด ์ด๋ฒคํธ ํธ๋ค๋ฌ ํ๋กํผํฐ ๋ฐฉ์์ ํ๋์ด์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋กํ ์ ์๋ ๋ฐ๋ฉด, addEventListener ๋ฉ์๋๋ ํ๋ ์ด์์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋ก ํ ์ ์์ผ๋ฉฐ ๋ฑ๋ก๋ ์์๋๋ก ํธ์ถ๋ฉ๋๋ค. ํ์ง๋ง, ์ฐธ์กฐ๊ฐ ๋์ผํ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ ์ค๋ณต ๋ฑ๋ก๋์ง ์๊ณ ํ ๊ฐ๋ง ๋ฑ๋ก๋ฉ๋๋ค.
์ด๋ฒคํธ ํธ๋ค๋ฌ ์ ๊ฑฐ
addEventListener ๋ฉ์๋๋ก ๋ฑ๋กํ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ์ ๊ฑฐํ๋ ค๋ฉด EventTarget.prototype.removeEventListener ๋ฉ์๋์ addEventListener์ ๋์ผํ ์ธ์๋ฅผ ์ ๋ฌํด ์ฌ์ฉํฉ๋๋ค. (์ผ์นํ์ง ์์ผ๋ฉด ์ ๊ฑฐ X)
<!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>
<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๋ก ์๋ฌต์ ์ผ๋ก ๋ช ๋ช ๋๊ธฐ ๋๋ฌธ์ event๋ฅผ ํตํด ์ด๋ฒคํธ ๊ฐ์ฒด๋ฅผ ์ ๋ฌ๋ฐ์์ผ ํฉ๋๋ค.
์ด๋ฒคํธ ๊ฐ์ฒด์ ์์ ๊ตฌ์กฐ
์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด ์ด๋ฒคํธ ํ์ ์ ๋ฐ๋ผ ๋ค์๊ณผ ๊ฐ์ด ์์ ๊ตฌ์กฐ๋ฅผ ๊ฐ๋ ๋ค์ํ ํ์ ์ ์ด๋ฒคํธ ๊ฐ์ฒด๊ฐ ์์ฑ๋ฉ๋๋ค.
์ ๊ทธ๋ฆผ์ Event, UIEvent, MouseEvent ๋ฑ ๋ชจ๋ ์์ฑ์ ํจ์์ ๋๋ค. ๋ฐ๋ผ์ ๋ค์๊ณผ ๊ฐ์ด ์์ฑ์ ํจ์๋ฅผ ํธ์ถํ์ฌ ์ด๋ฒคํธ ๊ฐ์ฒด๋ฅผ ์์ฑํ ์ ์์ต๋๋ค.
<!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 ์ธํฐํ์ด์ค
Event ์ธํฐํ์ด์ค๋ DOM ๋ด์์ ๋ฐ์ํ ์ด๋ฒคํธ์ ์ํด ์์ฑ๋๊ณ ์ด๋ฒคํธ ๊ฐ์ฒด๋ก ๋ชจ๋ ์ด๋ฒคํธ ๊ฐ์ฒด์ ๊ณตํต ํ๋กํผํฐ๊ฐ ์ ์๋์ด ์๊ณ FocuseEvent, 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 ์ธํฐํ์ด์ค, ์ฆ Event.prototype์ ์ ์๋์ด ์๋ ์ด๋ฒคํธ ๊ด๋ จ ํ๋กํผํฐ๋ UIEvent, CustomEvent, MouseEvent ๋ฑ ๋ชจ๋ ํ์ ์ด๋ฒคํธ ๊ฐ์ฒด์ ์์๋ฉ๋๋ค. ๋ชจ๋ ์ด๋ฒคํธ ๊ฐ์ฒด๊ฐ ์์๋ฐ๋ ๊ณตํต ํ๋กํผํฐ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
๊ณตํต ํ๋กํผํฐ | ์ค๋ช | ํ์ |
type | ์ด๋ฒคํธ ํ์ | string |
target | ์ด๋ฒคํธ๋ฅผ ๋ฐ์์ํจ DOM ์์ | DOM ์์ ๋ ธ๋ |
currentTarget | ์ด๋ฒคํธ ํธ๋ค๋ฌ๊ฐ ๋ฐ์ธ๋ฉ๋ DOM ์์ | DOM ์์ ๋ ธ๋ |
eventPhase | ์ด๋ฒคํธ ์ ํ ๋จ๊ณ(0: ์ด๋ฒคํธ ์์, 1: ์บก์ณ๋ง ๋จ๊ณ, 2: ํ๊น ๋จ๊ณ, 3: ๋ฒ๋ธ๋ง ๋จ๊ณ) | number |
bubbles | ์ด๋ฒคํธ๋ฅผ ๋ฒ๋ธ๋ง์ผ๋ก ์ ํํ๋์ง ์ฌ๋ถ | boolean |
cancelable | preventDefault ๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ ์ด๋ฒคํธ์ ๊ธฐ๋ณธ ๋์์ ์ทจ์ํ ์ ์๋์ง ์ฌ๋ถ | boolean |
defaultPrevented | preventDefault ๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ ์ด๋ฒคํธ๋ฅผ ์ทจ์ํ๋์ง ์ฌ๋ถ | boolean |
isTrusted | ์ฌ์ฉ์์ ํ์์ ์ํด ๋ฐ์ํ ์ด๋ฒคํธ์ธ์ง ์ฌ๋ถ | boolean |
timeStamp | ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ ์๊ฐ(1970/01/01/00:00:00๋ถํฐ ๊ฒฝ๊ณผํ ๋ฐ๋ฆฌ์ด) | number |
๋ง์ฐ์ค ์ ๋ณด ์ทจ๋
MouseEvent ํ์ ์ ์ด๋ฒคํธ ๊ฐ์ฒด๋ ๋ค์๊ณผ ๊ฐ์ ๊ณ ์ ํ๋กํผํฐ๋ฅผ ๊ฐ์ง๋๋ค.
- ๋ง์ฐ์ค ํฌ์ธํฐ์ ์ขํ ์ ๋ณด๋ฅผ ๋ํ๋ด๋ ํ๋กํผํฐ : screenX/screenY, clientX/clientY, pageX/pageY, offsetX, offsetY
- ๋ฒํผ ์ ๋ณด๋ฅผ ๋ํ๋ด๋ ํ๋กํผํฐ : altKey, ctrlKey, shiftKey, button
ํค๋ณด๋ ์ ๋ณด ์ทจ๋
KeyboardEvent ํ์ ์ ์ด๋ฒคํธ ๊ฐ์ฒด๋ altKey, ctrlKey, shiftKey, metaKey, key, keyCode ๊ฐ์ ๊ณ ์ ์ ํ๋กํผํฐ๋ฅผ ๊ฐ์ต๋๋ค.
์ด๋ฒคํธ ์ ํ
์ด๋ฒคํธ ์ ํ๋ DOM ํธ๋ฆฌ ์์ ์กด์ฌํ๋ DOM ์์ ๋ ธ๋์์ ๋ฐ์ํ ์ด๋ฒคํธ๊ฐ DOM ํธ๋ฆฌ๋ฅผ ํตํด ์ ํ๋๋ ๊ฒ์ ๋๋ค.
์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด ์์ฑ๋ ์ด๋ฒคํธ ๊ฐ์ฒด๊ฐ ์ด๋ฒคํธ๋ฅผ ๋ฐ์์ํจ DOM ์์์ ์ด๋ฒคํธ ํ๊น์ ์ค์ฌ์ผ๋ก DOM ํธ๋ฆฌ๋ฅผ ํตํด ์ ํ๋ฉ๋๋ค. ์ด๋, ์ด๋ฒคํธ ์ ํ๋ ์ด๋ฒคํธ ๊ฐ์ฒด๊ฐ ์ ํ๋๋ ๋ฐฉํฅ์ ๋ฐ๋ผ ๋ค์๊ณผ ๊ฐ์ด 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>
- ul ์์์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฐ์ธ๋ฉํ๊ณ ul ์์์ ํ์ ์์์ธ li ์์๋ฅผ ํด๋ฆญํ์ฌ ์ด๋ฒคํธ๋ฅผ ๋ฐ์ํ๋ฉด ํด๋ฆญ ์ด๋ฒคํธ ๊ฐ์ฒด๊ฐ ์์ฑ๋๊ณ ํด๋ฆญ๋ li ์์๊ฐ ์ด๋ฒคํธ ํ๊น์ด๋จ
- ์บก์ณ๋ง ๋จ๊ณ : ํด๋ฆญ ์ด๋ฒคํธ๋ window์์ ์์ํด์ ์ด๋ฒคํธ ํ๊น ๋ฐฉํฅ์ผ๋ก ์ ํ
- ํ๊น ๋จ๊ณ : ์ด๋ฒคํธ ๊ฐ์ฒด๋ ์ด๋ฒคํธ๋ฅผ ๋ฐ์์ํจ ์ด๋ฒคํธ ํ๊น์ ๋๋ฌ
- ๋ฒ๋ธ๋ง ๋จ๊ณ : ์ด๋ฒคํธ ๊ฐ์ฒด๋ ์ด๋ฒคํธ ํ๊น์์ ์์ํด์ window ๋ฐฉํฅ์ผ๋ก ์ ํ
- ์ด๋ฒคํธ ํธ๋ค๋ฌ ์ดํธ๋ฆฌ๋ทฐํธ/ํ๋กํผํฐ ๋ฐฉ์์ผ๋ก ๋ฑ๋กํ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ ํ๊น ๋จ๊ณ์ ๋ฒ๋ธ๋ง ๋จ๊ณ์ ์ด๋ฒคํธ๋ง ์บ์นํ ์ ์์ง๋ง, addEventListener ๋ฉ์๋ ๋ฐฉ์์ผ๋ก ๋ฑ๋กํ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ ๋ฉ์๋์ 3๋ฒ์งธ ์ธ์๋ก true๋ฅผ ์ ๋ฌํ๋ฉด ์บก์ฒ๋ง ๋จ๊ณ์ ์ด๋ฒคํธ๋ ์ ๋ณ์ ์ผ๋ก ์บ์นํ ์ ์์
์ด์ฒ๋ผ ์ด๋ฒคํธ๋ ์ด๋ฒคํธ๋ฅผ ๋ฐ์์ํจ ์ด๋ฒคํธ ํ๊น์ ๋ฌผ๋ก ์์ DOM ์์์์๋ ์บ์นํ ์ ์์ต๋๋ค. ์ฆ, DOM ํธ๋ฆฌ๋ฅผ ํตํด ์ ํ๋๋ ์ด๋ฒคํธ๋ ์ด๋ฒคํธ ํจ์ค(๊ฒฝ๋ก)์ ์์นํ ๋ชจ๋ DOM ์์์์ ์บ์นํ ์ ์์ต๋๋ค.
๋๋ถ๋ถ์ ์ด๋ฒคํธ๋ ์บก์ฒ๋๊ณผ ๋ฒ๋ธ๋ง์ ํตํด ์ ํ๋์ง๋ง, ํฌ์ปค์ค ์ด๋ฒคํธ focus/blur, ๋ฆฌ์์ค ์ด๋ฒคํธ load/unload/abort/error, ๋ง์ฐ์ค ์ด๋ฒคํธ mouseenter/mouseleave๋ event.bubbles์ ๊ฐ์ด ๋ชจ๋ false๋ผ ๋ฒ๋ธ๋ง์ ํตํด ์ ํ๋์ง ์์ต๋๋ค. ๋ฐ๋ผ์ ์์ ์์์์ ์บ์นํด์ผ ํ๋ค๋ฉด ๋ค๋ฅธ ์ด๋ฒคํธ๋ก ๋์ฒดํ์ฌ ์ฌ์ฉํฉ๋๋ค.
์ด๋ฒคํธ ์์
์ด๋ฒคํธ ์์(event delegation)์ ์ฌ๋ฌ ๊ฐ์ ํ์ DOM ์์์ ๊ฐ๊ฐ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋กํ๋ ๋์ ํ๋์ ์์ 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 }) {
// ์ด๋ฒคํธ๋ฅผ ๋ฐ์์ํจ ์์(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>
์ด์ฒ๋ผ ์ด๋ฒคํธ ์์์ ํตํด ํ์ DOM ์์์์ ๋ฐ์ํ ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํ ๋ ์์ ์์์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋กํ๊ธฐ ๋๋ฌธ์ ์ด๋ฒคํธ ํ๊น์ ๊ฒ์ฌํ์ง ์์ผ๋ฉด ๊ฐ๋ฐ์๊ฐ ๊ธฐ๋ํ DOM ์์๊ฐ ์๋ ๋ค๋ฅธ ๊ณณ์์ ์ด๋ฒคํธ๊ฐ ๋ฐ์๋ ์ ์๋ค๋ ์ ์ ์ฃผ์ํด์ผ ํฉ๋๋ค.
DOM ์์์ ๊ธฐ๋ณธ ๋์ ์กฐ๊ฑด
DOM ์์๋ ์ ๋ง๋ค ๊ธฐ๋ณธ ๋์์ ๊ฐ์ง๊ณ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, a ์์๋ฅผ ํด๋ฆญํ๋ฉด href ์ดํธ๋ฆฌ๋ทฐํธ์ ์ง์ ๋ ๋งํฌ๋ก ์ด๋ํ๊ณ , checkbox/radio ์์๋ฅผ ํด๋ฆญํ๋ฉด ์ฒดํฌ/ํด์ ๋ฉ๋๋ค.
DOM ์์์ ๊ธฐ๋ณธ ๋์ ์ค๋จ
์ด๋ฒคํธ ๊ฐ์ฒด์ 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 ์์์์ ๋ฐ์ํ ํด๋ฆญ ์ด๋ฒคํธ๋ฅผ ์์ DOM ์์์ธ container ์์๊ฐ ์บ์นํ์ฌ ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌ
- ํ์ ์์ ์ค์์ btn2 ์์๋ ์ด๋ฒคํธ ์ ํ๊ฐ ์ค๋จ๋์ด ์์ฒด์ ์ผ๋ก ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌ
์ด์ฒ๋ผ stopPropagation ๋ฉ์๋๋ ํ์ DOM ์์์ ์ด๋ฒคํธ๋ฅผ ๊ฐ๋ณ์ ์ผ๋ก ์ฒ๋ฆฌํ๊ธฐ ์ํด ์ด๋ฒคํธ ์ ํ๋ฅผ ์ค๋จ์ํต๋๋ค.
์ด๋ฒคํธ ํธ๋ค๋ฌ ๋ด๋ถ์ this
์ด๋ฒคํธ ํธ๋ค๋ฌ ์ดํธ๋ฆฌ๋ทฐํธ ๋ฐฉ์
์ด๋ฒคํธ ํธ๋ค๋ฌ ์ดํธ๋ฆฌ๋ทฐํธ์ ๊ฐ์ผ๋ก ์ง์ ํ ๋ฌธ์์ด์ ์ฌ์ค ์๋ฌต์ ์ผ๋ก ์์ฑ๋๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ์ ๋ฌธ์ด๊ธฐ ๋๋ฌธ์ ์ด๋ฒคํธ ํธ๋ค๋ฌ์ ์ํด ์ผ๋ฐ ํจ์๋ก ํธ์ถ๋ฉ๋๋ค. ๋ฐ๋ผ์ ํจ์ ๋ด๋ถ์ this๋ ์ ์ญ ๊ฐ์ฒด์ธ window๋ฅผ ๊ฐ๋ฆฌํต๋๋ค. ๋จ, ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ํธ์ถํ ๋ ์ธ์๋ก ์ ๋ฌํ this๋ ์ด๋ฒคํธ๋ฅผ ๋ฐ์ธ๋ฉํ DOM ์์๋ฅผ ๊ฐ๋ฆฌํต๋๋ค.
<!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>
์ด์ฒ๋ผ ์ด๋ฒคํธ ํธ๋ค๋ฌ ์ดํธ๋ฆฌ๋ทฐํธ ๋ฐฉ์์ ์ํด ์๋ฌต์ ์ผ๋ก ์์ฑ๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ ๋ด๋ถ์ this๋ ์ด๋ฒคํธ๋ฅผ ๋ฐ์ธ๋ฉํ DOM ์์๋ฅผ ๊ฐ๋ฅดํค๋ฉฐ ์ด๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ ํ๋กํผํฐ ๋ฐฉ์๊ณผ ๋์ผํฉ๋๋ค.
์ด๋ฒคํธ ํธ๋ค๋ฌ ํ๋กํผํฐ ๋ฐฉ์๊ณผ 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>
์ด๋ฒคํธ ํธ๋ค๋ฌ์ ์ธ์ ์ ๋ฌ
์ด๋ฒคํธ ํธ๋ค๋ฌ ์ดํธ๋ฆฌ๋ทฐํธ ๋ฐฉ์์ ํจ์ ํธ์ถ๋ฌธ์ ์ฌ์ฉํ ๋ ์ธ์๋ฅผ ์ ๋ฌํ๋ฉด ๋์ง๋ง, ์ด๋ฒคํธ ํธ๋ค๋ฌ ํ๋กํผํฐ ๋ฐฉ์๊ณผ 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>
์ปค์คํ ์ด๋ฒคํธ
์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด ์๋ฌต์ ์ผ๋ก ์์ฑ๋๋ ์ด๋ฒคํธ ๊ฐ์ฒด๋ ๋ฐ์ํ ์ด๋ฒคํธ์ ์ข ๋ฅ์ ๋ฐ๋ผ ์ด๋ฒคํธ ํ์ ์ด ๊ฒฐ์ ๋์ง๋ง Event, UIEvent, MouseEvent ๊ฐ์ ์ด๋ฒคํธ ์์ฑ์ ํจ์๋ฅผ ํธ์ถํ์ฌ ๋ช ์์ ์ผ๋ก ์์ฑํ ์ด๋ฒคํธ ๊ฐ์ฒด๋ ์์์ ์ด๋ฒคํธ ํ์ ์ ์ง์ ํ ์ ์์ต๋๋ค. ์ด์ฒ๋ผ ๊ฐ๋ฐ์์ ์๋๋ก ์์ฑ๋ ์ด๋ฒคํธ๋ฅผ ์ปค์คํ ์ด๋ฒคํธ๋ผ ํฉ๋๋ค.
์ปค์คํ ์ด๋ฒคํธ ์์ฑ
์ด๋ฒคํธ ์์ฑ์ ํจ์๋ ์ฒซ ๋ฒ์งธ ์ธ์๋ก ์ด๋ฒคํธ ํ์ ์ ๋ํ๋ด๋ ๋ฌธ์์ด์ ์ ๋ฌ๋ฐ์ต๋๋ค. ์ด๋ ๊ธฐ์กด ์ด๋ฒคํธ ํ์ ์ด ์๋ ์์์ ๋ฌธ์์ด์ ์ฌ์ฉํด ์๋ก์ด ์ด๋ฒคํธ ํ์ ์ ์ง์ ํ ์๋ ์์ต๋๋ค.
์ผ๋ฐ์ ์ผ๋ก ์๋์ ๊ฐ์ด CustomEvent ์ด๋ฒคํธ ์์ฑ์ ํจ์๋ฅผ ์ฌ์ฉํด ์ปค์คํ ์ด๋ฒคํธ๋ฅผ ์์ฑํฉ๋๋ค.
// KeyboardEvent ์์ฑ์ ํจ์๋ก keyup ์ด๋ฒคํธ ํ์
์ ์ปค์คํ
์ด๋ฒคํธ ๊ฐ์ฒด๋ฅผ ์์ฑ
const keyboardEvent = new KeyboardEvent('keyup');
console.log(keyboardEvent.type); // keyup
// CustomEvent ์์ฑ์ ํจ์๋ก foo ์ด๋ฒคํธ ํ์
์ ์ปค์คํ
์ด๋ฒคํธ ๊ฐ์ฒด๋ฅผ ์์ฑ
const customEvent = new CustomEvent('foo');
console.log(customEvent.type); // foo
// MouseEvent ์์ฑ์ ํจ์๋ก click ์ด๋ฒคํธ ํ์
์ ์ปค์คํ
์ด๋ฒคํธ ๊ฐ์ฒด๋ฅผ ์์ฑ
const customEvent = new MouseEvent('click');
console.log(customEvent.type); // click
console.log(customEvent.bubbles); // false
console.log(customEvent.cancelable); // false
// MouseEvent ์์ฑ์ ํจ์๋ก click ์ด๋ฒคํธ ํ์
์ ์ปค์คํ
์ด๋ฒคํธ ๊ฐ์ฒด๋ฅผ ์์ฑ
const customEvent = new MouseEvent('click', {
bubbles: true,
cancelable: true
});
console.log(customEvent.bubbles); // true
console.log(customEvent.cancelable); // true
// 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
// InputEvent ์์ฑ์ ํจ์๋ก foo ์ด๋ฒคํธ ํ์
์ ์ปค์คํ
์ด๋ฒคํธ ๊ฐ์ฒด๋ฅผ ์์ฑ
const customEvent = new InputEvent('foo');
console.log(customEvent.isTrusted); // false
- ๋ฒ๋ธ๋ง๋์ง ์์ผ๋ฉฐ, preventDefault ๋ฉ์๋๋ก ์ทจ์ํ ์๋ ์์ (bubbles์ cancelable์ด false)
- ์ปค์คํ ์ด๋ฒคํธ ๊ฐ์ฒด์ bubbles/cancelable ํ๋กํผํฐ๋ฅผ true๋ก ์ค์ ํ๋ ค๋ฉด ์ด๋ฒคํธ ์์ฑ์ ํจ์์ ๋ ๋ฒ์งธ ์ธ์๋ก bubbles/cancelable ํ๋กํผํฐ๋ฅผ ๊ฐ๋ ๊ฐ์ฒด๋ฅผ ์ ๋ฌํด์ผ ํจ
- ์ด๋ฒคํธ ํ์ ์ ๋ฐ๋ผ ๊ฐ์ง๋ ์ด๋ฒคํธ ๊ณ ์ ์ ํ๋กํผํฐ ๊ฐ์ ์ง์ ํ ์ ์์
- ์ด๋ฒคํธ ์์ฑ์ ํจ์๋ก ์์ฑํ ์ปค์คํ ์ด๋ฒคํธ๋ isTrusted ํ๋กํผํฐ์ ๊ฐ์ด ์ธ์ ๋ false
์ปค์คํ ์ด๋ฒคํธ ๋์คํจ์น
์์ฑ๋ ์ปค์คํ ์ด๋ฒคํธ๋ dispatchEvent ๋ฉ์๋๋ก ๋์คํจ์น(์ด๋ฒคํธ๋ฅผ ๋ฐ์์ํค๋ ํ์)ํ ์ ์์ต๋๋ค. 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>
dispatchEvent ๋ฉ์๋๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋๊ธฐ ์ฒ๋ฆฌ ๋ฐฉ์์ผ๋ก ํธ์ถํ๊ธฐ ๋๋ฌธ์ ๋์คํจ์น ํ๊ธฐ ์ด์ ์ ์ปค์คํ ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋กํด์ผ ํฉ๋๋ค. ๋ฐ๋ผ์ ๊ธฐ์กด ์ด๋ฒคํธ ํ์ ์ด ์๋ ์์์ ์ด๋ฒคํธ ํ์ ์ ์ง์ ํ์ฌ ์ปค์คํ ์ด๋ฒคํธ ๊ฐ์ฒด๋ฅผ ์์ฑํ ๊ฒฝ์ฐ ๋ฐ๋์ addEventListener ๋ฉ์๋ ๋ฐฉ์์ผ๋ก ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋กํด์ผ ํฉ๋๋ค.
<!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>
[์ถ์ฒ] ๋ชจ๋ ์๋ฐ์คํฌ๋ฆฝํธ Deep Dive
https://frontsom.tistory.com/12
'JavaScript > ๋ชจ๋ ์๋ฐ์คํฌ๋ฆฝํธ Deep Dive' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[JavaScript] Ajax (0) | 2022.08.15 |
---|---|
[JavaScript] ํ์ด๋จธ (0) | 2022.08.13 |
[JavaScript] DOM (0) | 2022.08.12 |
[JavaScript] ๋ธ๋ผ์ฐ์ ์ ๋ ๋๋ง ๊ณผ์ (0) | 2022.08.09 |
[JavaScript] Set๊ณผ Map (0) | 2022.08.07 |
- Total
- Today
- Yesterday
- ํ๋ก๊ทธ๋๋จธ์ค
- ๋ค์ด๋๋ฏน ํ๋ก๊ทธ๋๋ฐ
- ์ ์ญ ๋ณ์
- ์ด๋ถํ์
- JavaScript
- fp
- http
- ํ๋กํ ์ฝ
- ๋คํธ์ํฌ
- ๊ฐ์ฒด์งํฅ ํ๋ก๊ทธ๋๋ฐ
- ํฌํฌ์ธํฐ
- ๋ฐฑ์ค javascript
- Baekjoon
- ์๊ณ ๋ฆฌ์ฆ
- ๋์์ธ ํจํด
- ๋ชจ๋ ์๋ฐ์คํฌ๋ฆฝํธ deep dive
- map
- ๋ ์์ปฌ ํ๊ฒฝ
- ํ๋กํผํฐ
- ์ฝ๋ฉํ ์คํธ
- TDD
- ์๋ฐ์คํฌ๋ฆฝํธ
- ์๋ฐ
- ์ด์์ฒด์
- ํจ์ํ ํ๋ก๊ทธ๋๋ฐ
- 2019 ์นด์นด์ค ๊ฐ๋ฐ์ ๊ฒจ์ธ ์ธํด
- ๋ฐฑ์ค
- ๋ฐฑ์ค node.js
- ์นด์นด์ค ์ธํด
- git
์ผ | ์ | ํ | ์ | ๋ชฉ | ๊ธ | ํ |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |