-
1. ์๋ฐ์คํฌ๋ฆฝํธ ์ด๋ฒคํธ (JavaScript Event)
-
2. ์ด๋ฒคํธ ํธ๋ค๋ฌ (Event Handler)
-
3. JS์ addEventListener() ๋ฉ์๋
-
4. jQuery์ .on() ๋ฉ์๋
-
.on() ๋ฉ์๋
-
.one() (์ด๋ฒคํธ ํ ๋ฒ๋ง ์คํ)
-
.off() (์ด๋ฒคํธ ์ ๊ฑฐ)
-
5. on๊ณผ addEventListener ์ฐจ์ด์
-
5-1. ์๋ฐ์คํฌ๋ฆฝํธ ์ญ์ฌ & ์ ์ด์ฟผ๋ฆฌ์ on ๊ณผ Vanilla JavaScript
-
6. ๋ง์ฐ์ค ์ด๋ฒคํธ
-
6-1. ๋ง์ฐ์ค ํด๋ฆญ ์ด๋ฒคํธ
-
6-2. ๋ง์ฐ์ค ์ด๋ ๊ด๋ จ ์ด๋ฒคํธ
-
6-3. ๋ง์ฐ์ค ๋ฒํผ ๋ฐ ํ ๊ด๋ จ ์ด๋ฒคํธ
-
7. ํฌ์ปค์ค ์ด๋ฒคํธ
-
7-1. focus / blur (๋ฒ๋ธ๋ง X)
-
7-2. focusin / focusout (๋ฒ๋ธ๋ง O)
-
7-3. tabindex
-
8. ํค๋ณด๋ ์ด๋ฒคํธ
-
8-1. keydown & kepup
-
8-2. Enter & Escape
-
8-3. ํค ์กฐํฉ (Ctrl + S, Shift + A ๋ฑ)
-
8-4. ์ ๋ ฅ ํ๋์์ ์ค์๊ฐ ์ ๋ ฅ ๊ฐ์งํ ๋ ์ ์ฉํ ์ฝ๋
-
9. ์ด๋ฒคํธ ํ๋ก์ฐ, ๋ฒ๋ธ๋ง๊ณผ ์บก์ณ๋ง, target
-
9-1. ๋ฒ๋ธ๋ง(Bubbling)์ด๋?
-
9-2. ๋ฒ๋ธ๋ง(Bubbling)์ ๋ฐฉ์งํด์ผ ํ๋ ๊ฒฝ์ฐ
-
9-3. ์บก์ฒ๋ง(Capturing)์ด๋?
-
9-4. ํ๊ฒ(target)์ด๋?
-
10. ์ฐธ๊ณ ์๋ฃ

๋ด๊ฐ ๋ณด๋ ค๊ณ ๋ง๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ
๐ฆ๋ชฉํ
์ด๋ฒคํธ, ์ด๋ฒคํธ ํธ๋ค๋ฌ, ์ด๋ฒคํธ ๋ฒ์ค ๋ฐ addEventListener์ ๋ํด ์์๋ณด์.
๊ทธ๋ฆฌ๊ณ jQuery์ Vanilla JavaScript์์ ์ด๋ฒคํธ๋ฅผ ๋ค๋ฃจ๋ ๋ฒ์ ๋ํด ์์๋ณด์.
๋ค์ ํ ๋ฒ ๋งํ์ง๋ง jQuery๋ ํ๋ ์น ๊ฐ๋ฐ์์ ํ์์ ์ธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ง๋ง, ์ด์ ๋ Vanilla JavaScript(์์ JS)๋ React, Vue, Svelte ๊ฐ์ ํ๋ ์์ํฌ๊ฐ ๋์ฒดํ๋ฉด์ ์ฌ์ฉ์ด ์ค์ด๋ค๊ณ ์๋ค. ๊ทธ๋์ addEventListener ์์ฃผ๋ก๋ง ์ ๋ฆฌํ๊ณ ์์ํ๊ฒ ์ด๋ฒคํธ ์ข
๋ฅ๋ง ๊ถ๊ธํ ์ฌ๋์ 6๋ฒ๋ถํฐ ์ฝ์ผ๋ฉด ๋๋ค.
1. ์๋ฐ์คํฌ๋ฆฝํธ ์ด๋ฒคํธ (JavaScript Event)
์ด๋ฒคํธ(Event)๋ ์ฌ์ฉ์๋ ์์คํ
์ด ์น ํ์ด์ง์์ ์ผ์ผํค๋ ๋์์ด๋ค.
์๋ฅผ ๋ค์ด, ๋ฒํผ ํด๋ฆญ, ํค๋ณด๋ ์
๋ ฅ, ๋ง์ฐ์ค ์์ง์ ๋ฑ์ด ๋ชจ๋ ์ด๋ฒคํธ์ด๋ค.
์๋ฐ์คํฌ๋ฆฝํธ๋ ์ด ์ด๋ฒคํธ๋ฅผ ๊ฐ์งํ๊ณ , ๊ทธ์ ๋ํ ๋ฐ์(์์
)์ ์ค์ ํ๋ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด์ด๋ค.
์ฃผ์ ์ด๋ฒคํธ ์ข
๋ฅโผ
- ์ฌ์ฉ์ ์ ๋ ฅ ์ด๋ฒคํธ: click, keydown, keyup, mouseenter, focus, blur ๋ฑ
- ํผ ๊ด๋ จ ์ด๋ฒคํธ: submit, change, input ๋ฑ
- ๋ง์ฐ์ค ์ด๋ฒคํธ: click, mouseover, mouseout, mousemove ๋ฑ
- ๋ฌธ์ ์ํ ์ด๋ฒคํธ: load, resize, scroll ๋ฑ
2. ์ด๋ฒคํธ ํธ๋ค๋ฌ (Event Handler)
์ด๋ฒคํธ ํธ๋ค๋ฌ๋ ํน์ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ์ ๋ ์คํ๋๋ ์ฝ๋ฐฑ ํจ์์ด๋ค.
์๋ฐ์คํฌ๋ฆฝํธ์์๋ addEventListener() ํจ์๊ฐ ์ด๋ฒคํธ ํธ๋ค๋ฌ๊ฐ ์คํ๋๋๋ก ํ๋ ์ญํ ์ ํ๋ค.
์๋๋ click ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด, ํด๋น ๋ฒํผ์ ์ง์ ๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ๊ฐ ์คํ๋์ด ์๋ฆผ์ฐฝ์ด ๋จ๋ ์์ ์ฝ๋์ด๋ค.
document.getElementById('myButton').addEventListener('click', function() {
alert('๋ฒํผ์ด ํด๋ฆญ๋์์ต๋๋ค!');
});
๐ก ์ฝ๋ฐฑํจ์(Callback ํจ์)๋?
์ฝ๋ฐฑ ํจ์๋ ๋ค๋ฅธ ํจ์์ ์ธ์๋ก ์ ๋ฌ๋์ด ์คํ๋๋ ํจ์์ด๋ค. ๋ณดํต ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ ์ด๋ฒคํธ ํธ๋ค๋ง์์ ์ฌ์ฉ๋๋๋ฐ ์ด๋ค ํจ์๊ฐ ๋๋ ํ ์คํ๋ ์์ ์ ์ฝ๋ฐฑ ํจ์๋ก ๋๊ฒจ์ฃผ๋ ๋ฐฉ์์ด๋ค.
3. JS์ addEventListener() ๋ฉ์๋
element.addEventListener(event, callback, useCapture);
- element: ์ด๋ฒคํธ๋ฅผ ๊ฑธ๊ณ ์ ํ๋ DOM ์์
- event: ๋ฐ์ํ ์ด๋ฒคํธ์ ์ข ๋ฅ (์: 'click', 'keydown', 'mouseover' ๋ฑ)
- callback: ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ์ ๋ ์คํํ ์ด๋ฒคํธ ํธ๋ค๋ฌ ํจ์
- useCapture (์ต์ ): ์ด๋ฒคํธ ์บก์ฒ๋ง ๋จ๊ณ์์ ์ฒ๋ฆฌํ ์ง ์ฌ๋ถ - ๊ธฐ๋ณธ๊ฐ์ false ์, ์๋ต ๊ฐ๋ฅ
4. jQuery์ .on() ๋ฉ์๋
์์ ๋ฐ๋๋ผ ์๋ฐ ์คํฌ๋ฆฝํธ์์๋ addEventListener()๋ก ์ด๋ฒคํธ๋ฅผ ์ถ๊ฐํ๋ค.
ํ์ง๋ง jQuery๋ฅผ ์ฌ์ฉํ ๋๋ .on() ๋ฉ์๋๋ก ์ด๋ฒคํธ๋ฅผ ๋ฑ๋กํ๊ณ , ๋ถํ์ํ ์ด๋ฒคํธ๋ .off()๋ก ์ ๊ฑฐํ๋ค.
์ถํ์ ์ค๋ช
ํ๊ฒ ์ง๋ง .on() ๋ฉ์๋๋ ์ด์ ๊ฑฐ์ ์ฐ์ด์ง ์๋๋ค. addEventListener์ ๋นํด ๋จ์ ์ด ๋ง์ผ๋ฉฐ, ์ ์ฐ์ฑ์ด ๋จ์ด์ง๋ค. ๊ทธ๋์ ์ด๋ฒคํธ๋ฅผ ์ถ๊ฐ ํ ๋๋ addEventListener์ ์ฌ์ฉํ๋ ๊ฒ์ด ๊ถ์ฅ๋๋ค. ๊ทธ๋ฅ ์ ์ด์ฟผ๋ฆฌ์์๋ on์ด ์๋ค ์ ๋๋ก ์ดํดํ๊ณ ๋์ด ๊ฐ๋ ๊ฒ์ด ์ข๋ค.
.on() ๋ฉ์๋
$('#btn').on('click', function() {
$(this).css('font-size', '20px'); // ํด๋ฆญ ์ ๊ธ์ ํฌ๊ธฐ ๋ณ๊ฒฝ
});
$('#btn').on('mouseenter mouseleave', function() {
$(this).toggleClass('hovered'); // ๋ง์ฐ์ค๋ฅผ ์ฌ๋ฆฌ๋ฉด ํด๋์ค ์ถ๊ฐ/์ ๊ฑฐ
});
โญ ์ฃผ์์ฌํญ
๋์ ์ผ๋ก ์ถ๊ฐ๋ ์์์๋ ์ด๋ฒคํธ๋ฅผ ์ ์ฉํ๋ ค๋ฉด ๋ฐ๋์ ๋ถ๋ชจ ์์์ ์ด๋ฒคํธ๋ฅผ ์์ํด์ผ ํ๋ค.
$(document).on('click', '.dynamic-btn', function() {
alert('์๋ก ์ถ๊ฐ๋ ๋ฒํผ ํด๋ฆญ!');
});
์ด๋ฒคํธ๋ฅผ ์์ํ๋ค๋ ๊ฒ์ ๋ฌด์์ธ๊ฐ?
์๋ฅผ ๋ค์ด์ ์๋ฐ์คํฌ๋ฆฝํธ๋ก ํ์ด์ง ๋ก๋ ํ์ ๋์ ์ผ๋ก ์ถ๊ฐ๋ ๋ฒํผ์ด ์๋ค๊ณ ํด ๋ณด์. ์์น์ ์ผ๋ก ์ด ๋ฒํผ์ ์ด๋ฒคํธ๋ฅผ ์ง์ ๋ฑ๋กํ๋ ค๋ฉด ํด๋น ์์๊ฐ ์ด๋ฏธ ์กด์ฌํด์ผ ํ๋ค. ๊ทธ๋ ์ง ์์ผ๋ฉด ์ด๋ฒคํธ๋ฅผ ๋ฑ๋กํ ์๊ฐ ์๋ค.
์ด๋ ์ด๋ฒคํธ ์์์ ์ฌ์ฉํ๋ฉด, ๋ถ๋ชจ ์์์ ์ด๋ฒคํธ๋ฅผ ๋ฑ๋กํ๊ณ ์์ ์์์ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ์ ๋ ๊ทธ ์ด๋ฒคํธ๋ฅผ ๋ถ๋ชจ๊ฐ "๋๋ฆฌ"๋ก ์ฒ๋ฆฌํ๊ฒ ํ ์ ์๋ค.
<div id="parent">
<button class="btn">๋ฒํผ 1</button>
</div>
<script>
// ๋์ ์ผ๋ก ๋ฒํผ ์ถ๊ฐ
const newButton = document.createElement('button');
newButton.className = 'btn';
newButton.textContent = '๋ฒํผ 2';
document.getElementById('parent').appendChild(newButton);
// ๋ถ๋ชจ ์์์ ์ด๋ฒคํธ ์์
document.getElementById('parent').addEventListener('click', function(event) {
if (event.target && event.target.classList.contains('btn')) {
alert(`${event.target.textContent} ํด๋ฆญ๋จ!`);
}
});
</script>
์ ์ฝ๋๋ฅผ ์ดํด ๋ณด์.
#parent ๋ถ๋ชจ ์์์ click ์ด๋ฒคํธ๋ฅผ ์์ํ ์ํ์์, event.target์ ์ฌ์ฉํด์ ์ค์ ํด๋ฆญ๋ ์์๊ฐ .btn ํด๋์ค๋ฅผ ๊ฐ์ง๊ณ ์๋์ง ํ์ธ์ ํ๋ค. if๋ฌธ์ ์ดํด ๋ณด๋ฉด '๋ง์ฝ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ ์์๊ฐ 'btn' ํด๋์ค๋ฅผ ๊ฐ์ง๊ณ ์๋ค๋ฉด, ๊ทธ ์์์ ํ
์คํธ ๋ด์ฉ์ ์๋ฆผ์ผ๋ก ์ถ๋ ฅํ๋ผ.'๋ ์ฝ๋์ด๋ค. ์๋ฅผ ๋ค์ด, "๋ฒํผ 2"์ด๋ผ๋ ํ
์คํธ๋ฅผ ๊ฐ์ง ๋ฒํผ์ด ํด๋ฆญ๋๋ฉด, ์๋ฆผ์ฐฝ์ "๋ฒํผ 2 ํด๋ฆญ๋จ!"์ด ํ์๊ฐ ๋๋ค.
์ด๋ฒคํธ๊ฐ ๋ฐ์ํ ์์๋ฅผ ์ด๋ฒคํธ ํ๊ฒ(event.target)์ผ๋ก ํ์ธํด์, ๋ถ๋ชจ ์์์ click ์ด๋ฒคํธ๋ฅผ ๋ฑ๋กํ๊ณ , ์์ ์์๊ฐ ํด๋ฆญ๋๋ฉด ๋ถ๋ชจ์์ ๋ชจ๋ ์์ ์์์ ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํ๊ฒ ๋๋ฏ๋ก, ๋์ ์ผ๋ก ์ถ๊ฐ๋ ์์์๋ ์ด๋ฒคํธ๊ฐ ์๋์ผ๋ก ์ ์ฉ๋๋ ์๋ฆฌ์ด๋ค.
.one() (์ด๋ฒคํธ ํ ๋ฒ๋ง ์คํ)
$('#btn').one('click', function() {
alert('์ด ๋ฒํผ์ ํ ๋ฒ๋ง ํด๋ฆญํ ์ ์์ต๋๋ค.');
});
.off() (์ด๋ฒคํธ ์ ๊ฑฐ)
$('#btn').off('click'); // ํด๋ฆญ ์ด๋ฒคํธ ์ ๊ฑฐ
$('#btn').off(); // ๋ชจ๋ ์ด๋ฒคํธ ์ ๊ฑฐ
5. on๊ณผ addEventListener ์ฐจ์ด์
addEventListener๋ ์ต์ ์น ๊ฐ๋ฐ์์๋ ๊ถ์ฅํ๋ ๋ฐฉ์์ด๋ค. ์์ฆ์ addEventListener์ด ์๋์ ์ผ๋ก ์ฐ์๋ฅผ ์ ํ๊ณ ์๋ค๋ ์ฌ์ค์๋ ์ด๊ฒฌ์ด ์๋ค. ์ฌ๋ฌ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋กํ ์ ์๊ณ , ๋ฆฌ์ค๋๋ฅผ ๋์ ์ผ๋ก ์ถ๊ฐ/์ ๊ฑฐํ ์ ์์ผ๋ฉฐ. ์ด๋ฒคํธ ์บก์ฒ๋ง๊ณผ ๋ฒ๋ธ๋ง ์ต์
์ ์ธ๋ฐํ๊ฒ ์ ์ดํ ์ ์๊ธฐ ๋๋ฌธ์ ๋๊ฐ ๋ด๋ addEventListener์ด on ๋ณด๋ค๋ ํจ์ฌ ๋ฐ์ด๋๊ณ ์ ํธ๋๋ ๋ฐฉ์์ด๋ค.
on์ ๊ตฌํ ๋ธ๋ผ์ฐ์ ํธํ์ฑ ๋๋ฌธ์ ๊ฐ๋จํ ์ด๋ฒคํธ ์ฒ๋ฆฌ์ ์ฌ์ฉ๋๋ ์ ๋์ด๋ค. ํ์ง๋ง ๊ณต๋ถ๋ฅผ ํ๋ค๊ฐ on์ด ๋ฌด์์ธ์ง, addEventListener ๊ณผ์ ์ฐจ์ด๊ฐ ๋ฌด์์ธ์ง ๊ถ๊ธํ์ ๋ถ๋ค์ด ์์ ๊ฒ ๊ฐ์์ ๊ฐ๋จํ ์กฐ์ฌํ์ฌ ํฌ์คํ
์ ํ๊ฒ ๋์๋ค.
5-1. ์๋ฐ์คํฌ๋ฆฝํธ ์ญ์ฌ & ์ ์ด์ฟผ๋ฆฌ์ on ๊ณผ Vanilla JavaScript
โ ์ด๊ธฐ JavaScript (1995~2000๋
๋ ์ด๋ฐ
- on ์ด๋ฒคํธ ํธ๋ค๋ฌ(onclick, onmouseover)๊ฐ ์ฃผ๋ก ์ฌ์ฉ๋จ
โ DOM Level 2 (1998~2000๋
๋ ์ด๋ฐ)
- addEventListener ๋ฑ์ฅ, ์ฌ๋ฌ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ํ ์์์ ๋ฑ๋ก ๊ฐ๋ฅ
- ๊ตฌํ ๋ธ๋ผ์ฐ์ (IE)๋ addEventListener๋ฅผ ์ง์ํ์ง ์์์ on ๋ฐฉ์์ด ๊ณ์ ์ฌ์ฉ๋จ
โ jQuery (2006๋
)
- jQuery์์ on ๋ฉ์๋๋ฅผ ์ฌ์ฉํด ์ด๋ฒคํธ ํธ๋ค๋ง์ ๊ฐํธํ๊ฒ ์ ๊ณต.
- ์ฌ๋ฌ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋กํ ์ ์์ง๋ง ์ฑ๋ฅ์ addEventListener๋ณด๋ค๋ ๋จ์ด์ง.
โ Modern JavaScript (2010๋
๋ ํ๋ฐ ~ ํ์ฌ)
- addEventListener๊ฐ ์๋ฆฌ ์ก์. ์ต์ ๋ธ๋ผ์ฐ์ ์์ ์๋ฒฝํ๊ฒ ์ง์
- jQuery๋ ์ผ๋ถ์์ ์ฌ์ ํ ์ฌ์ฉ๋์ง๋ง, addEventListener๊ฐ ์๋์ ์ผ๋ก ๋ ๋ง์ด ์ฐ์
- ํ์ง๋จผ jQuery์ on์ ์ฌ์ ํ ์ผ๋ถ์์ ์ฌ์ฉ๋๊ณ ์์.
๊ฒฐ๋ก : addEventListener >>>>>>>> on
6. ๋ง์ฐ์ค ์ด๋ฒคํธ
์น ํ์ด์ง์์ ๋ง์ฐ์ค์ ๊ด๋ จ๋ ์ด๋ฒคํธ๋ ํฌ๊ฒ ํด๋ฆญ, ์ด๋, ๋ฒํผ ๋์ ๋ฑ์ผ๋ก ๋๋ ์ ์๋ค.

๋ง์ฐ์ค ์ด๋ฒคํธ ์ข ๋ฅ ( โ โ ๋ ์์ ํฌํจ ์ฌ๋ถ)
click ๋ง์ฐ์ค๋ฅผ ํด๋ฆญํ์ ๋ โ
dblclick ๋ง์ฐ์ค๋ฅผ ๋๋ธ ํด๋ฆญํ์ ๋ โ
contextmenu ๋ง์ฐ์ค ์ฐํด๋ฆญ ์ ๋ฐ์ โ
mousemove ๋ง์ฐ์ค๊ฐ ์ด๋ํ ๋ โ
mouseover ๋ง์ฐ์ค๊ฐ ์์ ์๋ก ์ฌ๋ผ์์ ๋ โ
mouseout ๋ง์ฐ์ค๊ฐ ์์์์ ๋๊ฐ ๋ โ
mouseenter ๋ง์ฐ์ค๊ฐ ์์ ์๋ก ์ฌ๋ผ์์ ๋ โ
mouseleave ๋ง์ฐ์ค๊ฐ ์์์์ ๋๊ฐ ๋ โ
mousedown ๋ง์ฐ์ค๋ฅผ ๋๋ ์ ๋ โ
mouseup ๋ง์ฐ์ค๋ฅผ ๋์ ๋ โ
wheel ๋ง์ฐ์ค ํ ์ ๊ตด๋ฆด ๋ โ
6-1. ๋ง์ฐ์ค ํด๋ฆญ ์ด๋ฒคํธ
- click ๋ง์ฐ์ค๋ฅผ ํด๋ฆญํ์ ๋ ๋ฐ์ (์ผ์ชฝ ๋ฒํผ)
- dblclick ๋ง์ฐ์ค๋ฅผ ๋๋ธ ํด๋ฆญํ์ ๋ ๋ฐ์
- contextmenu ๋ง์ฐ์ค ์ค๋ฅธ์ชฝ ๋ฒํผ ํด๋ฆญ ์ ๋ฐ์ (์ฐํด๋ฆญ ๋ฉ๋ด)
const box = document.querySelector('.box');
box.addEventListener('click', function() {
console.log('ํด๋ฆญ ์ด๋ฒคํธ ๋ฐ์!');
});
box.addEventListener('dblclick', function() {
console.log('๋๋ธ ํด๋ฆญ ์ด๋ฒคํธ ๋ฐ์!');
});
box.addEventListener('contextmenu', function(event) {
event.preventDefault(); // ๊ธฐ๋ณธ ์ฐํด๋ฆญ ๋ฉ๋ด ์ฐจ๋จ
console.log('์ฐํด๋ฆญ ๋ฉ๋ด ์ด๊ธฐ ๋ฐฉ์ง!');
});
6-2. ๋ง์ฐ์ค ์ด๋ ๊ด๋ จ ์ด๋ฒคํธ
- mousemove ๋ง์ฐ์ค๊ฐ ์์ ์์์ ์์ง์ผ ๋ ๋ฐ์
- mouseover ๋ง์ฐ์ค๊ฐ ์์ ์๋ก ์ฌ๋ผ์์ ๋ ๋ฐ์ (์์ ์์ ํฌํจ)
- mouseout ๋ง์ฐ์ค๊ฐ ์์์์ ๋๊ฐ ๋ ๋ฐ์ (์์ ์์ ํฌํจ)
- mouseenter ๋ง์ฐ์ค๊ฐ ์์ ์๋ก ์ฌ๋ผ์์ ๋ ๋ฐ์ (์์ ์์ ํฌํจ ์ ํจ)
- mouseleave ๋ง์ฐ์ค๊ฐ ์์์์ ๋๊ฐ ๋ ๋ฐ์ (์์ ์์ ํฌํจ ์ ํจ)
const box = document.querySelector('.box');
box.addEventListener('mousemove', function(event) {
console.log(`๋ง์ฐ์ค ์ด๋ ์ค! X: ${event.clientX}, Y: ${event.clientY}`);
});
box.addEventListener('mouseover', function() {
console.log('๋ง์ฐ์ค๊ฐ ์์ ์๋ก ์ฌ๋ผ์์ด์!');
});
box.addEventListener('mouseout', function() {
console.log('๋ง์ฐ์ค๊ฐ ์์ ๋ฐ์ผ๋ก ๋๊ฐ์ด์!');
});
โ
์ฐจ์ด์
- mouseover / mouseout โ ์์ ์์์๋ ๋ฐ์
- mouseenter / mouseleave โ ์์ ์์์๋ ๋ฐ์ ์ ํจ
6-3. ๋ง์ฐ์ค ๋ฒํผ ๋ฐ ํ ๊ด๋ จ ์ด๋ฒคํธ
- mousedown ๋ง์ฐ์ค ๋ฒํผ์ ๋๋ ์ ๋ ๋ฐ์
- mouseup ๋ง์ฐ์ค ๋ฒํผ์ ๋์ ๋ ๋ฐ์
- wheel ๋ง์ฐ์ค ํ ์ ๊ตด๋ ธ์ ๋ ๋ฐ์
const box = document.querySelector('.box');
box.addEventListener('mousedown', function() {
console.log('๋ง์ฐ์ค๋ฅผ ๋๋ ์ต๋๋ค!');
});
box.addEventListener('mouseup', function() {
console.log('๋ง์ฐ์ค๋ฅผ ๋์ต๋๋ค!');
});
document.addEventListener('wheel', function(event) {
console.log(`ํ ์คํฌ๋กค ๋ฐฉํฅ: ${event.deltaY > 0 ? '์๋' : '์'}`);
});
7. ํฌ์ปค์ค ์ด๋ฒคํธ
์
๋ ฅ ํ๋(input, textarea, select)๋ ๋ฒํผ ๋ฑ ํฌ์ปค์ค๋ฅผ ๋ฐ์ ์ ์๋ ์์์์ ๋ฐ์ํ๋ ์ด๋ฒคํธ์ด๋ค.
ํฌ์ปค์ค ์ด๋ฒคํธ ์ข ๋ฅ (๋ฒ๋ธ๋ง ์ฌ๋ถ)
- focus ์์์ ์์๊ฐ ํด๋ฆญ๋๊ฑฐ๋ ํญ์ผ๋ก ์ด๋ํ ๋ ์คํ๋จ โ (๋ฒ๋ธ๋ง ์ ๋จ)
- blur ์์์์ ์์๊ฐ ๋ค๋ฅธ ๊ณณ์ผ๋ก ํฌ์ปค์ค๊ฐ ์ด๋ํ ๋ ์คํ๋จ โ (๋ฒ๋ธ๋ง ์ ๋จ)
- focusin ์์์ ํฌ์ปค์ค๊ฐ ๋ง์ถฐ์ง ๋ ๋ฐ์ (focus์ ๊ฐ์ง๋ง ๋ฒ๋ธ๋ง O) โ
- focusout ์์์์ ํฌ์ปค์ค๊ฐ ๋น ์ง ๋ ๋ฐ์ (blur์ ๊ฐ์ง๋ง ๋ฒ๋ธ๋ง O) โ
7-1. focus / blur (๋ฒ๋ธ๋ง X)
const input = document.querySelector('input');
input.addEventListener('focus', function() {
console.log('์
๋ ฅ ํ๋์ ํฌ์ปค์ค๊ฐ ๋ง์ถฐ์ก์ต๋๋ค!');
});
input.addEventListener('blur', function() {
console.log('์
๋ ฅ ํ๋์์ ํฌ์ปค์ค๊ฐ ๋น ์ก์ต๋๋ค!');
});
7-2. focusin / focusout (๋ฒ๋ธ๋ง O)
const form = document.querySelector('form');
form.addEventListener('focusin', function(event) {
console.log(`ํฌ์ปค์ค๊ฐ ๋ค์ด์จ ์์: ${event.target.name}`);
});
form.addEventListener('focusout', function(event) {
console.log(`ํฌ์ปค์ค๊ฐ ๋น ์ง ์์: ${event.target.name}`);
});
โญ ๊ทธ๋์? ์ฌ๋ฌ ์์์์ ์ด๋ฒคํธ๋ฅผ ๊ฐ์งํ๋ ค๋ฉด focusin, focusout์ธ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข๋ค.
7-3. tabindex
์ผ๋ฐ์ ์ผ๋ก <button>์ด๋ <input> ์์๋์๋ง ํฌ์ปค์ค๊ฐ ์ ์ฉ๋์ง๋ง, tabindex="0" ์์ฑ์ ์ถ๊ฐํ๋ฉด <div>, <span> ๊ฐ์ ์์๋ ํฌ์ปค์ค๋ฅผ ๋ฐ์ ์ ์๊ณ , ํฌ์ปค์ค๊ฐ ๋ง์ถฐ์ก์ ๋ ์คํ์ผ ๋ณ๊ฒฝ ๊ฐ๋ฅ
<div tabindex="0">์ด DIV๋ ํฌ์ปค์ค๋ฅผ ๋ฐ์ ์ ์์ด์!</div>
const div = document.querySelector('div');
div.addEventListener('focus', function() {
div.style.backgroundColor = 'lightblue';
});
div.addEventListener('blur', function() {
div.style.backgroundColor = '';
});
์ด๋ฒคํธ | ์ค๋ช | ๋ฒ๋ธ๋ง ์ฌ๋ถ | ์ธ์ ์จ? |
focus | ์์์ ํฌ์ปค์ค๊ฐ ๋ง์ถฐ์ง ๋ | X | ์ ๋ ฅ ํ๋ ํด๋ฆญ |
blur | ์์์ ํฌ์ปค์ค๊ฐ ๋น ์ง๋ | X | ์ ๋ ฅ ํ ๋ค๋ฅธ ๊ณณ ํด๋ฆญ |
focusin | ์์์ ํฌ์ปค์ค๊ฐ ๋ง์ถฐ์ง ๋ | O | ํผ ์ ์ฒด์์ ํฌ์ปค์ค ๊ฐ์ง |
focusout | ์์์ ํฌ์ปค์ค๊ฐ ๋น ์ง๋ | O | ํผ ์ ์ฒด์์ ํฌ์ปค์ค ํด์ ๊ฐ์ง |
8. ํค๋ณด๋ ์ด๋ฒคํธ
์ฌ์ฉ์๊ฐ ํค๋ณด๋๋ฅผ ์
๋ ฅํ ๋ ๋ฐ์ํ๋ ์ด๋ฒคํธ
๋ณดํต ์
๋ ฅ ํ๋(input, textarea) ๋๋ ๋ฌธ์ ์ ์ฒด์์ ๋จ์ถํค ๊ธฐ๋ฅ์ ๊ตฌํํ ๋ ์ฌ์ฉ๋จ
ํค๋ณด๋ ์ด๋ฒคํธ ์ข ๋ฅ (๋ฒ๋ธ๋ง ์ฌ๋ถ)
- keydown์ ์ฃผ๋ก ์ฌ์ฉํ๊ณ , ํค ์ ๋ ฅ์ด ๋๋ ํ ๋์ํ๋ ค๋ฉด keyup์ ์ฌ์ฉ
- event.key๋ฅผ ํ์ฉํด ํน์ ํค ๊ฐ์ง ๊ฐ๋ฅ
- ๋จ์ถํค(Ctrl + S, Shift + A ๋ฑ)๋ฅผ ๋ง๋ค ๋ event.ctrlKey, event.shiftKey ์ฌ์ฉ
8-1. keydown & kepup
document.addEventListener('keydown', function(event) {
console.log(`ํค๋ค์ด: ${event.key} (${event.code})`);
});
document.addEventListener('keyup', function(event) {
console.log(`ํค์
: ${event.key} (${event.code})`);
});
- keydown: ํค๋ฅผ ๋๋ฅด๋ ์๊ฐ ๋ฐ์
- keyup: ํค๋ฅผ ๋ ๋ ๋ฐ์
- event.key โ ์ฌ์ฉ์๊ฐ ์ ๋ ฅํ ํค (์: "a", "Enter", "Shift")
- event.code โ ๋ฌผ๋ฆฌ์ ์ธ ํค์ ์ฝ๋ (์: "KeyA", "Enter", "ShiftLeft")
8-2. Enter & Escape
ํน์ ํค ๊ฐ์งํด์ ํน์ ๋์ ์คํ ๊ฐ๋ฅ
document.addEventListener('keydown', function(event) {
if (event.key === 'Enter') {
console.log('์ํฐ ํค๋ฅผ ๋๋ ์ต๋๋ค!');
} else if (event.key === 'Escape') {
console.log('ESC ํค๋ฅผ ๋๋ ์ต๋๋ค!');
}
});
8-3. ํค ์กฐํฉ (Ctrl + S, Shift + A ๋ฑ)
ํน์ ํค(Ctrl, Shift, Alt, Meta)๋ ์กฐํฉํ๋ฉด ๋จ์ถํค ๊ตฌํ ๊ฐ๋ฅํจ
event.preventDefault()๋ฅผ ์ฌ์ฉํ๋ฉด ๊ธฐ๋ณธ ๋์(๋ธ๋ผ์ฐ์ ์ ์ฅ ๋ฑ) ๋ฐฉ์ง ๊ฐ๋ฅํจ
document.addEventListener('keydown', function(event) {
if (event.ctrlKey && event.key === 's') {
event.preventDefault(); // ๊ธฐ๋ณธ ๋์(์: ๋ธ๋ผ์ฐ์ ์ ์ฅ) ๋ง๊ธฐ
console.log('Ctrl + S ๋จ์ถํค๊ฐ ๋๋ ธ์ต๋๋ค!');
}
});
8-4. ์ ๋ ฅ ํ๋์์ ์ค์๊ฐ ์ ๋ ฅ ๊ฐ์งํ ๋ ์ ์ฉํ ์ฝ๋
const input = document.querySelector('input');
input.addEventListener('keydown', function(event) {
console.log(`์
๋ ฅ ์ค: ${event.key}`);
});
input.addEventListener('keyup', function(event) {
console.log(`์
๋ ฅ ์๋ฃ: ${event.key}`);
});
9. ์ด๋ฒคํธ ํ๋ก์ฐ, ๋ฒ๋ธ๋ง๊ณผ ์บก์ณ๋ง, target

์๋ฐ์คํฌ๋ฆฝํธ์ ์ด๋ฒคํธ ํ๋ก์ฐ

์ด๋ฒคํธ ํ๋ก์ฐ๋ ์๋ฐ์คํฌ๋ฆฝํธ์์ ์ด๋ฒคํธ๊ฐ ์ด๋ป๊ฒ ์ ๋ฌ๋๋์ง ์ค๋ช
ํ๋ ๋ฐฉ์์ด๋ค.
์บก์ฒ๋ง: ์ด๋ฒคํธ๊ฐ ๋ถ๋ชจ์์ ์์์ผ๋ก ์ ๋ฌ๋จ
ํ๊ฒ: ์ด๋ฒคํธ๊ฐ ๋ชฉํ ์์์ ๋๋ฌํ๋ฉด, ๊ทธ๊ณณ์์ ์ฒ๋ฆฌ๊ฐ ์์๋จ
๋ฒ๋ธ๋ง: ์ด๋ฒคํธ๊ฐ ์์์์ ๋ถ๋ชจ๋ก ๋ค์ ์ ๋ฌ๋๋ค.
๋๋ถ๋ถ์ ๊ฒฝ์ฐ ๋ฒ๋ธ๋ง์ด ๊ธฐ๋ณธ์ผ๋ก ์ฌ์ฉ๋์ง๋ง, ์บก์ฒ๋ง ๋ ์ํ ๋ addEventListener์ true ์์ฑ์ผ๋ก ์ค์ ํ ์ ์๋ค.
9-1. ๋ฒ๋ธ๋ง(Bubbling)์ด๋?

์ด๋ฒคํธ๊ฐ ๋ฐ์ํ ์์์์ ์์ํ์ฌ ์์ ์์ (๋ถ๋ชจ, ์กฐ์ ์์)๋ก ์ ํ๋๋ ํ์์ด๋ค.
์๋ฅผ ๋ค์ด, <button>์ ํด๋ฆญํ๋ฉด ๊ทธ ํด๋ฆญ ์ด๋ฒคํธ๋ ๋ฒํผ โ ๋ถ๋ชจ <div> โ <body> ์์๋ก ์์ ์์๊น์ง ์ ๋ฌ๋๋ค.
์๋ ์ฝ๋๋ child ๋ฒํผ์ ํด๋ฆญํ๋ฉด ๋ถ๋ชจ ์์์ธ parent ๊น์ง ์ด๋ฒคํธ๊ฐ ์ ๋ฌ์ด ๋๋ ์์์ฝ๋์ด๋ค.
<div id="parent">
<button id="child">ํด๋ฆญํ์ธ์</button>
</div>
<script>
document.getElementById('parent').addEventListener('click', function() {
console.log('๐จ ๋ถ๋ชจ div ํด๋ฆญ๋จ!');
});
document.getElementById('child').addEventListener('click', function() {
console.log('๐ถ ๋ฒํผ ํด๋ฆญ๋จ!');
});
</script>
์ด๋ ๊ฒ ๋ฒ๋ธ๋ง์ ํ์ฉํ๋ฉด ๋ถ๋ชจ ์์์์ ์์ ์์์ ์ด๋ฒคํธ๋ฅผ ๊ฐ์งํ ์ ์์ด ํจ์จ์ ์ด์ง๋ง ๋ฐ๋๋ก ๋ฒ๋ธ๋ง์ ๋ง์์ผ ํ๋ ๊ฒฝ์ฐ๋ ์๊ธด๋ค. ๋ฒ๋ธ๋ง์ ๋ง์ผ๋ ค๋ฉด `event.stopPropagation()`์ ์ฌ์ฉํ๋ค.
document.getElementById('child').addEventListener('click', function(event) {
event.stopPropagation(); // ๋ถ๋ชจ ์์๋ก ์ด๋ฒคํธ ์ ํ ์ฐจ๋จ
console.log('๐ถ ๋ฒํผ ํด๋ฆญ๋จ! (๋ถ๋ชจ ์ด๋ฒคํธ ์คํ ์ ๋จ)');
});
9-2. ๋ฒ๋ธ๋ง(Bubbling)์ ๋ฐฉ์งํด์ผ ํ๋ ๊ฒฝ์ฐ

๋ชจ๋ฌ์ฐฝ์ ์์๋ก ๋ค ์ ์๋ค. ๋ชจ๋ฌ์ ๋ซ์ ๋ฐฉ๋ฒ์ผ๋ก๋ ๋ณดํต ๋ ๊ฐ์ง ๋ฐฉ๋ฒ์ด ์๋ค. '๋ซ๊ธฐ ๋ฒํผ'์ ํด๋ฆญํ๊ฑฐ๋, ๋ชจ๋ฌ ์ธ๋ถ๋ฅผ ํด๋ฆญํด์ ๋ซ์ ์ ์๋ค.
์ด ๋, ๋ชจ๋ฌ ์ธ๋ถ ํด๋ฆญ ์ ๋ซ๋ ๋์์ ์ค์ ํ๋ ค๋ฉด, ๋ชจ๋ฌ์ ์ธ๋ถ๋ฅผ ๊ฐ์ธ๊ณ ์๋ ๋ถ๋ชจ ์์์ธ #modal์ ํด๋ฆญ ์ด๋ฒคํธ๋ฅผ ์ค์ ํด์ผ ํ๋ค. ์ด ์ด๋ฒคํธ๋ก ๋ชจ๋ฌ ์ธ๋ถ๋ฅผ ํด๋ฆญํ๋ฉด alert('๋ชจ๋ฌ์ด ๋ซํ์ต๋๋ค.')๊ฐ ์คํ๋๊ณ ๋ชจ๋ฌ์ด ๋ซํ๋ ๋์์ด ์ํ๋๋ค. ํ์ง๋ง ๋ฌธ์ ๋ ๋ซ๊ธฐ ๋ฒํผ์ผ๋ก ๋ชจ๋ฌ์ ๋ซ์ ๋ ๋ฐ์ํ๋ค. ์ฌ๊ธฐ์, ๋ง์ฝ์ ๋ซ๊ธฐ ๋ฒํผ์ event.stopPropagation() ์ ๊ฑธ์ด ์ฃผ์ง ์์ผ๋ฉด ๋ฒ๋ธ๋ง์ด ์ผ์ด๋์ ๋ชจ๋ฌ์ด ๋ซํ๋ ํ์์ด ์ค๋ณต์ผ๋ก 2๋ฒ ์ํ์ด ๋๋ค.
<div id="modal">
<div id="modalContent">
<p>๋ชจ๋ฌ ๋ด์ฉ</p>
<button id="closeButton">๋ซ๊ธฐ</button>
</div>
</div>
// ๋ชจ๋ฌ ์์ญ์ ํด๋ฆญํ๋ฉด ๋ชจ๋ฌ์ ๋ซ๋ ๋์
document.getElementById('modal').addEventListener('click', function() {
alert('๋ชจ๋ฌ์ด ๋ซํ์ต๋๋ค.');
});
// ๋ซ๊ธฐ ๋ฒํผ ํด๋ฆญ ์ ๋ถ๋ชจ ์ด๋ฒคํธ ์ ํ ๋ฐฉ์ง
document.getElementById('closeButton').addEventListener('click', function(event) {
event.stopPropagation(); // ๋ถ๋ชจ ์ด๋ฒคํธ ์ ํ ๋ฐฉ์ง
alert('๋ซ๊ธฐ ๋ฒํผ ํด๋ฆญ๋จ');
});
๋ submit ๋ฒํผ์ผ๋ก ํผ ์ ์ถ์ ํ ๋, ํ์ด์ง๊ฐ ๋ฆฌ๋ก๋๋๋ ๊ฒ์ ๋ฐฉ์งํ๋ ์ฉ๋๋ก event.preventDefault()๋ฅผ ์ฌ์ฉํ๋ค.
ํ์๊ฐ์
์ํฉ์ ์๊ฐ ํด ๋ณด์. ์ฌ์ฉ์๊ฐ ์ด๋ฆ, ์ด๋ฉ์ผ, ๋น๋ฐ๋ฒํธ ๋ฑ์ ์
๋ ฅํ๊ณ ์ ์ถ ๋ฒํผ์ ํด๋ฆญํ๋๋ฐ, ๋ฌธ์ ๊ฐ ์๊ฒจ ํ์ด์ง๊ฐ ์๋ก ๊ณ ์นจ๋๋ฉด ์ฌ์ฉ์๊ฐ ๋ค์ ๋ชจ๋ ์ ๋ณด๋ฅผ ์
๋ ฅํด์ผ ํ๋ ์ํฉ์ด ์๊ธด๋ค.
์๋ฅผ ๋ค์ด, ๋น๋ฐ๋ฒํธ๊ฐ ์๋ชป ์
๋ ฅ๋ ๊ฒฝ์ฐ, ํผ์ ์ ์ถํ๊ณ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ์ค์๊ฐ์ผ๋ก ํ์ํ๋ ค๋ฉด ํ์ด์ง๊ฐ ์๋ก ๊ณ ์นจ๋์ง ์์์ผ ํ๋ค. ๊ฐ๋ฐ์๋ ๋จ์ํ ์๋ชป๋ ํญ๋ชฉ์ ๋ํ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ํ๋ฉด์ ํ์ํด ์ฃผ๊ณ , ์ฌ์ฉ์๊ฐ ๊ธฐ์กด ์
๋ ฅ๊ฐ์ ๊ทธ๋๋ก ์ ์งํ๊ณ , ์์ ๋ง ํ ์ ์๋๋ก ํ๋ ๊ฒ์ด UX ์ธก๋ฉด์์ ํจ์ฌ ๋ ๊น๋ํ๋ค.
event.preventDefault()์ AJAX๋ฅผ ํจ๊ป ์ฐ๋ฉด ์๋ฒ์ ๋ฐ์ดํฐ๋ฅผ ๋น๋๊ธฐ์ ์ผ๋ก ๊ตํํ๋ฉด์ ํ์ด์ง ๋ฆฌ๋ก๋ ์์ด ๊ฒฐ๊ณผ๋ฅผ ์ฒ๋ฆฌํ ์ ์๊ธฐ ๋๋ฌธ์ ์ฌ์ฉ์๊ฐ ์
๋ ฅํ ๋ฐ์ดํฐ๋ฅผ ๋ค์ ์
๋ ฅํ๊ณ ๊ฒ์ฆ์ ๋ฐ์์ผ ํ๊ธฐ ๋๋ฌธ์ ๋ถํธํจ์ ๊ฒช์ง ์์๋ ๋๋ค.
(์ฐ๋ค ๋ณด๋ ๋ง์ด ์ด๋ ต๊ฒ ์ ํ๋๋ฐ ์๋ ์ฝ๋๋ก ํ์ธ ๊ฐ๋ฅํ๋ค)
document.getElementById('myForm').addEventListener('submit', function(event) {
event.preventDefault(); // ํ์ด์ง ๋ฆฌ๋ก๋ ๋ฐฉ์ง
// ๋น๋๊ธฐ ๋ฐ์ดํฐ ์ฒ๋ฆฌ ์์ (AJAX)
const formData = new FormData(this);
fetch('/submit', {
method: 'POST',
body: formData,
})
.then(response => response.json())
.then(data => {
console.log('ํผ ๋ฐ์ดํฐ ์ ์ก ์ฑ๊ณต', data);
})
.catch(error => {
console.error('ํผ ์ ์ถ ์คํจ', error);
});
});
9-3. ์บก์ฒ๋ง(Capturing)์ด๋?

๋ฐ๋๋ก, ์ด๋ฒคํธ๊ฐ ์ต์์ ์์์์ ์์ํ์ฌ ํ์ ์์๋ก ์ ๋ฌ๋๋ ๋ฐฉ์์ ์บก์ฒ๋ง(Capturing)์ด๋ผ๊ณ ํ๋๋ฐ ๋ฐ๋๋ก ๋ถ๋ชจ์ div์ click ์ด๋ฒคํธ๊ฐ ์คํ๋๋ฉด, ์์์ ์ด๋ฒคํธ๋ ์คํ๋๋ ๊ฒ์ด๋ค. ํ์ง๋ง ์บก์ฒ๋ง์ ์ ์ฌ์ฉ๋์ง ์๋๋ค. ์๋ํ๋ฉด ๊ธฐ๋ณธ์ ์ผ๋ก ๋ธ๋ผ์ฐ์ ๋ ๋ฒ๋ธ๋ง์ ์ฐ์ ์ฌ์ฉํ๋ค. ์ด ๋ถ๋ถ์ ์ ํ์ฉ๋์ง ์๋ ๋ถ๋ถ์ด๋ฏ๋ก ์ฌ๊ธฐ๊น์ง๋ง ์ ๋ฆฌํ๋ค.
9-4. ํ๊ฒ(target)์ด๋?
target์ ์๋ฐ์คํฌ๋ฆฝํธ ์ด๋ฒคํธ ๊ฐ์ฒด์ ์์ฑ์ผ๋ก, ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ ์ค์ DOM ์์๋ฅผ ์ฐธ์กฐํ๋ค. ์ฃผ๋ก ์ด๋ฒคํธ ํธ๋ค๋ฌ์์ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ ๋์ ์์๋ฅผ ์๊ธฐ ์ํด ์ฌ์ฉ๋๋ ์์ฑ์ด๋ค.
์๋ ์ฝ๋์์event.target์ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ ์์๋ฅผ ๊ฐ๋ฆฌํจ๋ค. ๊ทธ๋์ myButton์ ํด๋ฆญํ๋ฉด event.target์ ๋ฐ๋ก ํด๋ฆญ๋ ๋ฒํผ ์์๋ฅผ ๋ฐํํ๋ค.
document.getElementById('myButton').addEventListener('click', function(event) {
console.log(event.target); // ํด๋ฆญํ ์ค์ ์์๊ฐ ์ถ๋ ฅ๋จ
});
์ฌ๋ฌ ์์ ์์๊ฐ ์์ ๋, ์ด๋ฒคํธ ์์์ด ์ผ์ด๋์ ๋ถ๋ชจ ์์์์ ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํ ์ ์๋ค. ์ด๋ event.target์ ์ฌ์ฉํ์ฌ ์ค์ ํด๋ฆญ๋ ์์ ์์๋ฅผ ํ์ธํ ์ ์๋ค.
document.getElementById('parent').addEventListener('click', function(event) {
if (event.target && event.target.matches('button')) {
alert('๋ฒํผ์ด ํด๋ฆญ๋จ!');
}
});
10. ์ฐธ๊ณ ์๋ฃ
1. chatGPT์ ๊ถ๊ธํ ๋ถ๋ถ์ ๋ฌผ์ด ๊ฐ๋ฉด์ ํฌ์คํ
์ ์์ฑํ์
2. ํฌ์คํ
์์ฑ์ ๋์์ ์ฃผ์ ๋ธ๋ก๊ทธ
[Javascript] ๋ง์ฐ์ค ์ด๋ฒคํธ / ๋๋๊ทธ ์ค ๋๋กญ (Drag and drop)
๐ก ์ด ํฌ์คํ ์ ์ด๋ฒคํธ ๋ง์ฐ์ค ์ด๋ฒคํธ ์ค ๋๋๊ทธ ์ค ๋๋กญ ๋ํด ๊ณต๋ถํ๋ฉฐ ์ ๋ฆฌํ ๋ด์ฉ์ ๋๋ค. ํน์ฌ๋ ์ผ๋ถ ์ฌ๋ฐ๋ฅด์ง ์์ ์ ๋ณด๊ฐ ์์ ์์ ์ง์ ํด์ฃผ์๋ฉด ์ ์ ํ ๋กํ๊ฒ ์ต๋๋ค.๋ง์ฐ์ค ์ด๋ฒคํธ์
velog.io
[JS-์ค๊ธํธ-์ด๋ฒคํธ] 3. ๋ง์ฐ์ค ์ด๋ฒคํธ
์ฌ๋๋ค์ด ์ปดํจํฐ์ ์ํธ ์์ฉํ๋ ๊ฐ์ฅ ์ผ๋ฐ์ ์ธ ๋ฐฉ๋ฒ ์ค ํ๋๋ ๋ง์ฐ์ค๋ก ์๋ ค์ง ํฌ์ธํ ์ฅ์น๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ๋๋ค. ๋ง์ฐ์ค ์ด๋ฒคํธ ๋ง๋๋ณด๊ธฐ JavaScript์์ ๋ง์ฐ์ค๋ฅผ ๋ค๋ฃจ๋ ์ฃผ๋ ๋ฐฉ๋ฒ์ ์ด๋ฒคํธ
cpro95.tistory.com
์ด๋ฒคํธ ๋ฒ๋ธ๋ง๊ณผ ์ด๋ฒคํธ ์บก์ฒ๋ง, ์ด๋ฒคํธ ์์
๋ค์ ์ฝ๋๋ฅผ ๋ณด์.๋ฒํผ์ ํด๋ฆญ ์ด๋ฒคํธ๋ฅผ ํ ๋นํ๊ณ , ํด๋ฆญ๋์์ ๋ console.log๊ฐ ์ถ๋ ฅ๋๋๋ก ํ์๋ค.button์ ํด๋ฆญํ๋ฉด ์ด๋ค ์ผ์ด ๋ฒ์ด์ง๊น?image๋ฒํผ์ ํด๋ฆญ ์ด๋ฒคํธ๊ฐ ์คํ๋๊ณ , ์ฝ์์๋ 'button'์ด ์ถ
velog.io
'ํ๋ก๊ทธ๋๋ฐ์ธ์ด > JavaScript' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ

๋ด๊ฐ ๋ณด๋ ค๊ณ ๋ง๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ
๐ฆ๋ชฉํ
์ด๋ฒคํธ, ์ด๋ฒคํธ ํธ๋ค๋ฌ, ์ด๋ฒคํธ ๋ฒ์ค ๋ฐ addEventListener์ ๋ํด ์์๋ณด์.
๊ทธ๋ฆฌ๊ณ jQuery์ Vanilla JavaScript์์ ์ด๋ฒคํธ๋ฅผ ๋ค๋ฃจ๋ ๋ฒ์ ๋ํด ์์๋ณด์.
๋ค์ ํ ๋ฒ ๋งํ์ง๋ง jQuery๋ ํ๋ ์น ๊ฐ๋ฐ์์ ํ์์ ์ธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ง๋ง, ์ด์ ๋ Vanilla JavaScript(์์ JS)๋ React, Vue, Svelte ๊ฐ์ ํ๋ ์์ํฌ๊ฐ ๋์ฒดํ๋ฉด์ ์ฌ์ฉ์ด ์ค์ด๋ค๊ณ ์๋ค. ๊ทธ๋์ addEventListener ์์ฃผ๋ก๋ง ์ ๋ฆฌํ๊ณ ์์ํ๊ฒ ์ด๋ฒคํธ ์ข
๋ฅ๋ง ๊ถ๊ธํ ์ฌ๋์ 6๋ฒ๋ถํฐ ์ฝ์ผ๋ฉด ๋๋ค.
1. ์๋ฐ์คํฌ๋ฆฝํธ ์ด๋ฒคํธ (JavaScript Event)
์ด๋ฒคํธ(Event)๋ ์ฌ์ฉ์๋ ์์คํ
์ด ์น ํ์ด์ง์์ ์ผ์ผํค๋ ๋์์ด๋ค.
์๋ฅผ ๋ค์ด, ๋ฒํผ ํด๋ฆญ, ํค๋ณด๋ ์
๋ ฅ, ๋ง์ฐ์ค ์์ง์ ๋ฑ์ด ๋ชจ๋ ์ด๋ฒคํธ์ด๋ค.
์๋ฐ์คํฌ๋ฆฝํธ๋ ์ด ์ด๋ฒคํธ๋ฅผ ๊ฐ์งํ๊ณ , ๊ทธ์ ๋ํ ๋ฐ์(์์
)์ ์ค์ ํ๋ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด์ด๋ค.
์ฃผ์ ์ด๋ฒคํธ ์ข
๋ฅโผ
- ์ฌ์ฉ์ ์ ๋ ฅ ์ด๋ฒคํธ: click, keydown, keyup, mouseenter, focus, blur ๋ฑ
- ํผ ๊ด๋ จ ์ด๋ฒคํธ: submit, change, input ๋ฑ
- ๋ง์ฐ์ค ์ด๋ฒคํธ: click, mouseover, mouseout, mousemove ๋ฑ
- ๋ฌธ์ ์ํ ์ด๋ฒคํธ: load, resize, scroll ๋ฑ
2. ์ด๋ฒคํธ ํธ๋ค๋ฌ (Event Handler)
์ด๋ฒคํธ ํธ๋ค๋ฌ๋ ํน์ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ์ ๋ ์คํ๋๋ ์ฝ๋ฐฑ ํจ์์ด๋ค.
์๋ฐ์คํฌ๋ฆฝํธ์์๋ addEventListener() ํจ์๊ฐ ์ด๋ฒคํธ ํธ๋ค๋ฌ๊ฐ ์คํ๋๋๋ก ํ๋ ์ญํ ์ ํ๋ค.
์๋๋ click ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด, ํด๋น ๋ฒํผ์ ์ง์ ๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ๊ฐ ์คํ๋์ด ์๋ฆผ์ฐฝ์ด ๋จ๋ ์์ ์ฝ๋์ด๋ค.
document.getElementById('myButton').addEventListener('click', function() { alert('๋ฒํผ์ด ํด๋ฆญ๋์์ต๋๋ค!'); });
๐ก ์ฝ๋ฐฑํจ์(Callback ํจ์)๋?
์ฝ๋ฐฑ ํจ์๋ ๋ค๋ฅธ ํจ์์ ์ธ์๋ก ์ ๋ฌ๋์ด ์คํ๋๋ ํจ์์ด๋ค. ๋ณดํต ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ ์ด๋ฒคํธ ํธ๋ค๋ง์์ ์ฌ์ฉ๋๋๋ฐ ์ด๋ค ํจ์๊ฐ ๋๋ ํ ์คํ๋ ์์ ์ ์ฝ๋ฐฑ ํจ์๋ก ๋๊ฒจ์ฃผ๋ ๋ฐฉ์์ด๋ค.
3. JS์ addEventListener() ๋ฉ์๋
element.addEventListener(event, callback, useCapture);
- element: ์ด๋ฒคํธ๋ฅผ ๊ฑธ๊ณ ์ ํ๋ DOM ์์
- event: ๋ฐ์ํ ์ด๋ฒคํธ์ ์ข ๋ฅ (์: 'click', 'keydown', 'mouseover' ๋ฑ)
- callback: ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ์ ๋ ์คํํ ์ด๋ฒคํธ ํธ๋ค๋ฌ ํจ์
- useCapture (์ต์ ): ์ด๋ฒคํธ ์บก์ฒ๋ง ๋จ๊ณ์์ ์ฒ๋ฆฌํ ์ง ์ฌ๋ถ - ๊ธฐ๋ณธ๊ฐ์ false ์, ์๋ต ๊ฐ๋ฅ
4. jQuery์ .on() ๋ฉ์๋
์์ ๋ฐ๋๋ผ ์๋ฐ ์คํฌ๋ฆฝํธ์์๋ addEventListener()๋ก ์ด๋ฒคํธ๋ฅผ ์ถ๊ฐํ๋ค.
ํ์ง๋ง jQuery๋ฅผ ์ฌ์ฉํ ๋๋ .on() ๋ฉ์๋๋ก ์ด๋ฒคํธ๋ฅผ ๋ฑ๋กํ๊ณ , ๋ถํ์ํ ์ด๋ฒคํธ๋ .off()๋ก ์ ๊ฑฐํ๋ค.
์ถํ์ ์ค๋ช
ํ๊ฒ ์ง๋ง .on() ๋ฉ์๋๋ ์ด์ ๊ฑฐ์ ์ฐ์ด์ง ์๋๋ค. addEventListener์ ๋นํด ๋จ์ ์ด ๋ง์ผ๋ฉฐ, ์ ์ฐ์ฑ์ด ๋จ์ด์ง๋ค. ๊ทธ๋์ ์ด๋ฒคํธ๋ฅผ ์ถ๊ฐ ํ ๋๋ addEventListener์ ์ฌ์ฉํ๋ ๊ฒ์ด ๊ถ์ฅ๋๋ค. ๊ทธ๋ฅ ์ ์ด์ฟผ๋ฆฌ์์๋ on์ด ์๋ค ์ ๋๋ก ์ดํดํ๊ณ ๋์ด ๊ฐ๋ ๊ฒ์ด ์ข๋ค.
.on() ๋ฉ์๋
$('#btn').on('click', function() { $(this).css('font-size', '20px'); // ํด๋ฆญ ์ ๊ธ์ ํฌ๊ธฐ ๋ณ๊ฒฝ });
$('#btn').on('mouseenter mouseleave', function() { $(this).toggleClass('hovered'); // ๋ง์ฐ์ค๋ฅผ ์ฌ๋ฆฌ๋ฉด ํด๋์ค ์ถ๊ฐ/์ ๊ฑฐ });
โญ ์ฃผ์์ฌํญ
๋์ ์ผ๋ก ์ถ๊ฐ๋ ์์์๋ ์ด๋ฒคํธ๋ฅผ ์ ์ฉํ๋ ค๋ฉด ๋ฐ๋์ ๋ถ๋ชจ ์์์ ์ด๋ฒคํธ๋ฅผ ์์ํด์ผ ํ๋ค.
$(document).on('click', '.dynamic-btn', function() { alert('์๋ก ์ถ๊ฐ๋ ๋ฒํผ ํด๋ฆญ!'); });
์ด๋ฒคํธ๋ฅผ ์์ํ๋ค๋ ๊ฒ์ ๋ฌด์์ธ๊ฐ?
์๋ฅผ ๋ค์ด์ ์๋ฐ์คํฌ๋ฆฝํธ๋ก ํ์ด์ง ๋ก๋ ํ์ ๋์ ์ผ๋ก ์ถ๊ฐ๋ ๋ฒํผ์ด ์๋ค๊ณ ํด ๋ณด์. ์์น์ ์ผ๋ก ์ด ๋ฒํผ์ ์ด๋ฒคํธ๋ฅผ ์ง์ ๋ฑ๋กํ๋ ค๋ฉด ํด๋น ์์๊ฐ ์ด๋ฏธ ์กด์ฌํด์ผ ํ๋ค. ๊ทธ๋ ์ง ์์ผ๋ฉด ์ด๋ฒคํธ๋ฅผ ๋ฑ๋กํ ์๊ฐ ์๋ค.
์ด๋ ์ด๋ฒคํธ ์์์ ์ฌ์ฉํ๋ฉด, ๋ถ๋ชจ ์์์ ์ด๋ฒคํธ๋ฅผ ๋ฑ๋กํ๊ณ ์์ ์์์ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ์ ๋ ๊ทธ ์ด๋ฒคํธ๋ฅผ ๋ถ๋ชจ๊ฐ "๋๋ฆฌ"๋ก ์ฒ๋ฆฌํ๊ฒ ํ ์ ์๋ค.
<div id="parent"> <button class="btn">๋ฒํผ 1</button> </div> <script> // ๋์ ์ผ๋ก ๋ฒํผ ์ถ๊ฐ const newButton = document.createElement('button'); newButton.className = 'btn'; newButton.textContent = '๋ฒํผ 2'; document.getElementById('parent').appendChild(newButton); // ๋ถ๋ชจ ์์์ ์ด๋ฒคํธ ์์ document.getElementById('parent').addEventListener('click', function(event) { if (event.target && event.target.classList.contains('btn')) { alert(`${event.target.textContent} ํด๋ฆญ๋จ!`); } }); </script>
์ ์ฝ๋๋ฅผ ์ดํด ๋ณด์.
#parent ๋ถ๋ชจ ์์์ click ์ด๋ฒคํธ๋ฅผ ์์ํ ์ํ์์, event.target์ ์ฌ์ฉํด์ ์ค์ ํด๋ฆญ๋ ์์๊ฐ .btn ํด๋์ค๋ฅผ ๊ฐ์ง๊ณ ์๋์ง ํ์ธ์ ํ๋ค. if๋ฌธ์ ์ดํด ๋ณด๋ฉด '๋ง์ฝ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ ์์๊ฐ 'btn' ํด๋์ค๋ฅผ ๊ฐ์ง๊ณ ์๋ค๋ฉด, ๊ทธ ์์์ ํ
์คํธ ๋ด์ฉ์ ์๋ฆผ์ผ๋ก ์ถ๋ ฅํ๋ผ.'๋ ์ฝ๋์ด๋ค. ์๋ฅผ ๋ค์ด, "๋ฒํผ 2"์ด๋ผ๋ ํ
์คํธ๋ฅผ ๊ฐ์ง ๋ฒํผ์ด ํด๋ฆญ๋๋ฉด, ์๋ฆผ์ฐฝ์ "๋ฒํผ 2 ํด๋ฆญ๋จ!"์ด ํ์๊ฐ ๋๋ค.
์ด๋ฒคํธ๊ฐ ๋ฐ์ํ ์์๋ฅผ ์ด๋ฒคํธ ํ๊ฒ(event.target)์ผ๋ก ํ์ธํด์, ๋ถ๋ชจ ์์์ click ์ด๋ฒคํธ๋ฅผ ๋ฑ๋กํ๊ณ , ์์ ์์๊ฐ ํด๋ฆญ๋๋ฉด ๋ถ๋ชจ์์ ๋ชจ๋ ์์ ์์์ ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํ๊ฒ ๋๋ฏ๋ก, ๋์ ์ผ๋ก ์ถ๊ฐ๋ ์์์๋ ์ด๋ฒคํธ๊ฐ ์๋์ผ๋ก ์ ์ฉ๋๋ ์๋ฆฌ์ด๋ค.
.one() (์ด๋ฒคํธ ํ ๋ฒ๋ง ์คํ)
$('#btn').one('click', function() { alert('์ด ๋ฒํผ์ ํ ๋ฒ๋ง ํด๋ฆญํ ์ ์์ต๋๋ค.'); });
.off() (์ด๋ฒคํธ ์ ๊ฑฐ)
$('#btn').off('click'); // ํด๋ฆญ ์ด๋ฒคํธ ์ ๊ฑฐ $('#btn').off(); // ๋ชจ๋ ์ด๋ฒคํธ ์ ๊ฑฐ
5. on๊ณผ addEventListener ์ฐจ์ด์
addEventListener๋ ์ต์ ์น ๊ฐ๋ฐ์์๋ ๊ถ์ฅํ๋ ๋ฐฉ์์ด๋ค. ์์ฆ์ addEventListener์ด ์๋์ ์ผ๋ก ์ฐ์๋ฅผ ์ ํ๊ณ ์๋ค๋ ์ฌ์ค์๋ ์ด๊ฒฌ์ด ์๋ค. ์ฌ๋ฌ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋กํ ์ ์๊ณ , ๋ฆฌ์ค๋๋ฅผ ๋์ ์ผ๋ก ์ถ๊ฐ/์ ๊ฑฐํ ์ ์์ผ๋ฉฐ. ์ด๋ฒคํธ ์บก์ฒ๋ง๊ณผ ๋ฒ๋ธ๋ง ์ต์
์ ์ธ๋ฐํ๊ฒ ์ ์ดํ ์ ์๊ธฐ ๋๋ฌธ์ ๋๊ฐ ๋ด๋ addEventListener์ด on ๋ณด๋ค๋ ํจ์ฌ ๋ฐ์ด๋๊ณ ์ ํธ๋๋ ๋ฐฉ์์ด๋ค.
on์ ๊ตฌํ ๋ธ๋ผ์ฐ์ ํธํ์ฑ ๋๋ฌธ์ ๊ฐ๋จํ ์ด๋ฒคํธ ์ฒ๋ฆฌ์ ์ฌ์ฉ๋๋ ์ ๋์ด๋ค. ํ์ง๋ง ๊ณต๋ถ๋ฅผ ํ๋ค๊ฐ on์ด ๋ฌด์์ธ์ง, addEventListener ๊ณผ์ ์ฐจ์ด๊ฐ ๋ฌด์์ธ์ง ๊ถ๊ธํ์ ๋ถ๋ค์ด ์์ ๊ฒ ๊ฐ์์ ๊ฐ๋จํ ์กฐ์ฌํ์ฌ ํฌ์คํ
์ ํ๊ฒ ๋์๋ค.
5-1. ์๋ฐ์คํฌ๋ฆฝํธ ์ญ์ฌ & ์ ์ด์ฟผ๋ฆฌ์ on ๊ณผ Vanilla JavaScript
โ ์ด๊ธฐ JavaScript (1995~2000๋
๋ ์ด๋ฐ
- on ์ด๋ฒคํธ ํธ๋ค๋ฌ(onclick, onmouseover)๊ฐ ์ฃผ๋ก ์ฌ์ฉ๋จ
โ DOM Level 2 (1998~2000๋
๋ ์ด๋ฐ)
- addEventListener ๋ฑ์ฅ, ์ฌ๋ฌ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ํ ์์์ ๋ฑ๋ก ๊ฐ๋ฅ
- ๊ตฌํ ๋ธ๋ผ์ฐ์ (IE)๋ addEventListener๋ฅผ ์ง์ํ์ง ์์์ on ๋ฐฉ์์ด ๊ณ์ ์ฌ์ฉ๋จ
โ jQuery (2006๋
)
- jQuery์์ on ๋ฉ์๋๋ฅผ ์ฌ์ฉํด ์ด๋ฒคํธ ํธ๋ค๋ง์ ๊ฐํธํ๊ฒ ์ ๊ณต.
- ์ฌ๋ฌ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฑ๋กํ ์ ์์ง๋ง ์ฑ๋ฅ์ addEventListener๋ณด๋ค๋ ๋จ์ด์ง.
โ Modern JavaScript (2010๋
๋ ํ๋ฐ ~ ํ์ฌ)
- addEventListener๊ฐ ์๋ฆฌ ์ก์. ์ต์ ๋ธ๋ผ์ฐ์ ์์ ์๋ฒฝํ๊ฒ ์ง์
- jQuery๋ ์ผ๋ถ์์ ์ฌ์ ํ ์ฌ์ฉ๋์ง๋ง, addEventListener๊ฐ ์๋์ ์ผ๋ก ๋ ๋ง์ด ์ฐ์
- ํ์ง๋จผ jQuery์ on์ ์ฌ์ ํ ์ผ๋ถ์์ ์ฌ์ฉ๋๊ณ ์์.
๊ฒฐ๋ก : addEventListener >>>>>>>> on
6. ๋ง์ฐ์ค ์ด๋ฒคํธ
์น ํ์ด์ง์์ ๋ง์ฐ์ค์ ๊ด๋ จ๋ ์ด๋ฒคํธ๋ ํฌ๊ฒ ํด๋ฆญ, ์ด๋, ๋ฒํผ ๋์ ๋ฑ์ผ๋ก ๋๋ ์ ์๋ค.

๋ง์ฐ์ค ์ด๋ฒคํธ ์ข ๋ฅ ( โ โ ๋ ์์ ํฌํจ ์ฌ๋ถ)
click ๋ง์ฐ์ค๋ฅผ ํด๋ฆญํ์ ๋ โ
dblclick ๋ง์ฐ์ค๋ฅผ ๋๋ธ ํด๋ฆญํ์ ๋ โ
contextmenu ๋ง์ฐ์ค ์ฐํด๋ฆญ ์ ๋ฐ์ โ
mousemove ๋ง์ฐ์ค๊ฐ ์ด๋ํ ๋ โ
mouseover ๋ง์ฐ์ค๊ฐ ์์ ์๋ก ์ฌ๋ผ์์ ๋ โ
mouseout ๋ง์ฐ์ค๊ฐ ์์์์ ๋๊ฐ ๋ โ
mouseenter ๋ง์ฐ์ค๊ฐ ์์ ์๋ก ์ฌ๋ผ์์ ๋ โ
mouseleave ๋ง์ฐ์ค๊ฐ ์์์์ ๋๊ฐ ๋ โ
mousedown ๋ง์ฐ์ค๋ฅผ ๋๋ ์ ๋ โ
mouseup ๋ง์ฐ์ค๋ฅผ ๋์ ๋ โ
wheel ๋ง์ฐ์ค ํ ์ ๊ตด๋ฆด ๋ โ
6-1. ๋ง์ฐ์ค ํด๋ฆญ ์ด๋ฒคํธ
- click ๋ง์ฐ์ค๋ฅผ ํด๋ฆญํ์ ๋ ๋ฐ์ (์ผ์ชฝ ๋ฒํผ)
- dblclick ๋ง์ฐ์ค๋ฅผ ๋๋ธ ํด๋ฆญํ์ ๋ ๋ฐ์
- contextmenu ๋ง์ฐ์ค ์ค๋ฅธ์ชฝ ๋ฒํผ ํด๋ฆญ ์ ๋ฐ์ (์ฐํด๋ฆญ ๋ฉ๋ด)
const box = document.querySelector('.box'); box.addEventListener('click', function() { console.log('ํด๋ฆญ ์ด๋ฒคํธ ๋ฐ์!'); }); box.addEventListener('dblclick', function() { console.log('๋๋ธ ํด๋ฆญ ์ด๋ฒคํธ ๋ฐ์!'); }); box.addEventListener('contextmenu', function(event) { event.preventDefault(); // ๊ธฐ๋ณธ ์ฐํด๋ฆญ ๋ฉ๋ด ์ฐจ๋จ console.log('์ฐํด๋ฆญ ๋ฉ๋ด ์ด๊ธฐ ๋ฐฉ์ง!'); });
6-2. ๋ง์ฐ์ค ์ด๋ ๊ด๋ จ ์ด๋ฒคํธ
- mousemove ๋ง์ฐ์ค๊ฐ ์์ ์์์ ์์ง์ผ ๋ ๋ฐ์
- mouseover ๋ง์ฐ์ค๊ฐ ์์ ์๋ก ์ฌ๋ผ์์ ๋ ๋ฐ์ (์์ ์์ ํฌํจ)
- mouseout ๋ง์ฐ์ค๊ฐ ์์์์ ๋๊ฐ ๋ ๋ฐ์ (์์ ์์ ํฌํจ)
- mouseenter ๋ง์ฐ์ค๊ฐ ์์ ์๋ก ์ฌ๋ผ์์ ๋ ๋ฐ์ (์์ ์์ ํฌํจ ์ ํจ)
- mouseleave ๋ง์ฐ์ค๊ฐ ์์์์ ๋๊ฐ ๋ ๋ฐ์ (์์ ์์ ํฌํจ ์ ํจ)
const box = document.querySelector('.box'); box.addEventListener('mousemove', function(event) { console.log(`๋ง์ฐ์ค ์ด๋ ์ค! X: ${event.clientX}, Y: ${event.clientY}`); }); box.addEventListener('mouseover', function() { console.log('๋ง์ฐ์ค๊ฐ ์์ ์๋ก ์ฌ๋ผ์์ด์!'); }); box.addEventListener('mouseout', function() { console.log('๋ง์ฐ์ค๊ฐ ์์ ๋ฐ์ผ๋ก ๋๊ฐ์ด์!'); });
โ
์ฐจ์ด์
- mouseover / mouseout โ ์์ ์์์๋ ๋ฐ์
- mouseenter / mouseleave โ ์์ ์์์๋ ๋ฐ์ ์ ํจ
6-3. ๋ง์ฐ์ค ๋ฒํผ ๋ฐ ํ ๊ด๋ จ ์ด๋ฒคํธ
- mousedown ๋ง์ฐ์ค ๋ฒํผ์ ๋๋ ์ ๋ ๋ฐ์
- mouseup ๋ง์ฐ์ค ๋ฒํผ์ ๋์ ๋ ๋ฐ์
- wheel ๋ง์ฐ์ค ํ ์ ๊ตด๋ ธ์ ๋ ๋ฐ์
const box = document.querySelector('.box'); box.addEventListener('mousedown', function() { console.log('๋ง์ฐ์ค๋ฅผ ๋๋ ์ต๋๋ค!'); }); box.addEventListener('mouseup', function() { console.log('๋ง์ฐ์ค๋ฅผ ๋์ต๋๋ค!'); }); document.addEventListener('wheel', function(event) { console.log(`ํ ์คํฌ๋กค ๋ฐฉํฅ: ${event.deltaY > 0 ? '์๋' : '์'}`); });
7. ํฌ์ปค์ค ์ด๋ฒคํธ
์
๋ ฅ ํ๋(input, textarea, select)๋ ๋ฒํผ ๋ฑ ํฌ์ปค์ค๋ฅผ ๋ฐ์ ์ ์๋ ์์์์ ๋ฐ์ํ๋ ์ด๋ฒคํธ์ด๋ค.
ํฌ์ปค์ค ์ด๋ฒคํธ ์ข ๋ฅ (๋ฒ๋ธ๋ง ์ฌ๋ถ)
- focus ์์์ ์์๊ฐ ํด๋ฆญ๋๊ฑฐ๋ ํญ์ผ๋ก ์ด๋ํ ๋ ์คํ๋จ โ (๋ฒ๋ธ๋ง ์ ๋จ)
- blur ์์์์ ์์๊ฐ ๋ค๋ฅธ ๊ณณ์ผ๋ก ํฌ์ปค์ค๊ฐ ์ด๋ํ ๋ ์คํ๋จ โ (๋ฒ๋ธ๋ง ์ ๋จ)
- focusin ์์์ ํฌ์ปค์ค๊ฐ ๋ง์ถฐ์ง ๋ ๋ฐ์ (focus์ ๊ฐ์ง๋ง ๋ฒ๋ธ๋ง O) โ
- focusout ์์์์ ํฌ์ปค์ค๊ฐ ๋น ์ง ๋ ๋ฐ์ (blur์ ๊ฐ์ง๋ง ๋ฒ๋ธ๋ง O) โ
7-1. focus / blur (๋ฒ๋ธ๋ง X)
const input = document.querySelector('input'); input.addEventListener('focus', function() { console.log('์
๋ ฅ ํ๋์ ํฌ์ปค์ค๊ฐ ๋ง์ถฐ์ก์ต๋๋ค!'); }); input.addEventListener('blur', function() { console.log('์
๋ ฅ ํ๋์์ ํฌ์ปค์ค๊ฐ ๋น ์ก์ต๋๋ค!'); });
7-2. focusin / focusout (๋ฒ๋ธ๋ง O)
const form = document.querySelector('form'); form.addEventListener('focusin', function(event) { console.log(`ํฌ์ปค์ค๊ฐ ๋ค์ด์จ ์์: ${event.target.name}`); }); form.addEventListener('focusout', function(event) { console.log(`ํฌ์ปค์ค๊ฐ ๋น ์ง ์์: ${event.target.name}`); });
โญ ๊ทธ๋์? ์ฌ๋ฌ ์์์์ ์ด๋ฒคํธ๋ฅผ ๊ฐ์งํ๋ ค๋ฉด focusin, focusout์ธ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข๋ค.
7-3. tabindex
์ผ๋ฐ์ ์ผ๋ก <button>์ด๋ <input> ์์๋์๋ง ํฌ์ปค์ค๊ฐ ์ ์ฉ๋์ง๋ง, tabindex="0" ์์ฑ์ ์ถ๊ฐํ๋ฉด <div>, <span> ๊ฐ์ ์์๋ ํฌ์ปค์ค๋ฅผ ๋ฐ์ ์ ์๊ณ , ํฌ์ปค์ค๊ฐ ๋ง์ถฐ์ก์ ๋ ์คํ์ผ ๋ณ๊ฒฝ ๊ฐ๋ฅ
<div tabindex="0">์ด DIV๋ ํฌ์ปค์ค๋ฅผ ๋ฐ์ ์ ์์ด์!</div>
const div = document.querySelector('div'); div.addEventListener('focus', function() { div.style.backgroundColor = 'lightblue'; }); div.addEventListener('blur', function() { div.style.backgroundColor = ''; });
์ด๋ฒคํธ | ์ค๋ช | ๋ฒ๋ธ๋ง ์ฌ๋ถ | ์ธ์ ์จ? |
focus | ์์์ ํฌ์ปค์ค๊ฐ ๋ง์ถฐ์ง ๋ | X | ์ ๋ ฅ ํ๋ ํด๋ฆญ |
blur | ์์์ ํฌ์ปค์ค๊ฐ ๋น ์ง๋ | X | ์ ๋ ฅ ํ ๋ค๋ฅธ ๊ณณ ํด๋ฆญ |
focusin | ์์์ ํฌ์ปค์ค๊ฐ ๋ง์ถฐ์ง ๋ | O | ํผ ์ ์ฒด์์ ํฌ์ปค์ค ๊ฐ์ง |
focusout | ์์์ ํฌ์ปค์ค๊ฐ ๋น ์ง๋ | O | ํผ ์ ์ฒด์์ ํฌ์ปค์ค ํด์ ๊ฐ์ง |
8. ํค๋ณด๋ ์ด๋ฒคํธ
์ฌ์ฉ์๊ฐ ํค๋ณด๋๋ฅผ ์
๋ ฅํ ๋ ๋ฐ์ํ๋ ์ด๋ฒคํธ
๋ณดํต ์
๋ ฅ ํ๋(input, textarea) ๋๋ ๋ฌธ์ ์ ์ฒด์์ ๋จ์ถํค ๊ธฐ๋ฅ์ ๊ตฌํํ ๋ ์ฌ์ฉ๋จ
ํค๋ณด๋ ์ด๋ฒคํธ ์ข ๋ฅ (๋ฒ๋ธ๋ง ์ฌ๋ถ)
- keydown์ ์ฃผ๋ก ์ฌ์ฉํ๊ณ , ํค ์ ๋ ฅ์ด ๋๋ ํ ๋์ํ๋ ค๋ฉด keyup์ ์ฌ์ฉ
- event.key๋ฅผ ํ์ฉํด ํน์ ํค ๊ฐ์ง ๊ฐ๋ฅ
- ๋จ์ถํค(Ctrl + S, Shift + A ๋ฑ)๋ฅผ ๋ง๋ค ๋ event.ctrlKey, event.shiftKey ์ฌ์ฉ
8-1. keydown & kepup
document.addEventListener('keydown', function(event) { console.log(`ํค๋ค์ด: ${event.key} (${event.code})`); }); document.addEventListener('keyup', function(event) { console.log(`ํค์
: ${event.key} (${event.code})`); });
- keydown: ํค๋ฅผ ๋๋ฅด๋ ์๊ฐ ๋ฐ์
- keyup: ํค๋ฅผ ๋ ๋ ๋ฐ์
- event.key โ ์ฌ์ฉ์๊ฐ ์ ๋ ฅํ ํค (์: "a", "Enter", "Shift")
- event.code โ ๋ฌผ๋ฆฌ์ ์ธ ํค์ ์ฝ๋ (์: "KeyA", "Enter", "ShiftLeft")
8-2. Enter & Escape
ํน์ ํค ๊ฐ์งํด์ ํน์ ๋์ ์คํ ๊ฐ๋ฅ
document.addEventListener('keydown', function(event) { if (event.key === 'Enter') { console.log('์ํฐ ํค๋ฅผ ๋๋ ์ต๋๋ค!'); } else if (event.key === 'Escape') { console.log('ESC ํค๋ฅผ ๋๋ ์ต๋๋ค!'); } });
8-3. ํค ์กฐํฉ (Ctrl + S, Shift + A ๋ฑ)
ํน์ ํค(Ctrl, Shift, Alt, Meta)๋ ์กฐํฉํ๋ฉด ๋จ์ถํค ๊ตฌํ ๊ฐ๋ฅํจ
event.preventDefault()๋ฅผ ์ฌ์ฉํ๋ฉด ๊ธฐ๋ณธ ๋์(๋ธ๋ผ์ฐ์ ์ ์ฅ ๋ฑ) ๋ฐฉ์ง ๊ฐ๋ฅํจ
document.addEventListener('keydown', function(event) { if (event.ctrlKey && event.key === 's') { event.preventDefault(); // ๊ธฐ๋ณธ ๋์(์: ๋ธ๋ผ์ฐ์ ์ ์ฅ) ๋ง๊ธฐ console.log('Ctrl + S ๋จ์ถํค๊ฐ ๋๋ ธ์ต๋๋ค!'); } });
8-4. ์ ๋ ฅ ํ๋์์ ์ค์๊ฐ ์ ๋ ฅ ๊ฐ์งํ ๋ ์ ์ฉํ ์ฝ๋
const input = document.querySelector('input'); input.addEventListener('keydown', function(event) { console.log(`์
๋ ฅ ์ค: ${event.key}`); }); input.addEventListener('keyup', function(event) { console.log(`์
๋ ฅ ์๋ฃ: ${event.key}`); });
9. ์ด๋ฒคํธ ํ๋ก์ฐ, ๋ฒ๋ธ๋ง๊ณผ ์บก์ณ๋ง, target

์๋ฐ์คํฌ๋ฆฝํธ์ ์ด๋ฒคํธ ํ๋ก์ฐ

์ด๋ฒคํธ ํ๋ก์ฐ๋ ์๋ฐ์คํฌ๋ฆฝํธ์์ ์ด๋ฒคํธ๊ฐ ์ด๋ป๊ฒ ์ ๋ฌ๋๋์ง ์ค๋ช
ํ๋ ๋ฐฉ์์ด๋ค.
์บก์ฒ๋ง: ์ด๋ฒคํธ๊ฐ ๋ถ๋ชจ์์ ์์์ผ๋ก ์ ๋ฌ๋จ
ํ๊ฒ: ์ด๋ฒคํธ๊ฐ ๋ชฉํ ์์์ ๋๋ฌํ๋ฉด, ๊ทธ๊ณณ์์ ์ฒ๋ฆฌ๊ฐ ์์๋จ
๋ฒ๋ธ๋ง: ์ด๋ฒคํธ๊ฐ ์์์์ ๋ถ๋ชจ๋ก ๋ค์ ์ ๋ฌ๋๋ค.
๋๋ถ๋ถ์ ๊ฒฝ์ฐ ๋ฒ๋ธ๋ง์ด ๊ธฐ๋ณธ์ผ๋ก ์ฌ์ฉ๋์ง๋ง, ์บก์ฒ๋ง ๋ ์ํ ๋ addEventListener์ true ์์ฑ์ผ๋ก ์ค์ ํ ์ ์๋ค.
9-1. ๋ฒ๋ธ๋ง(Bubbling)์ด๋?

์ด๋ฒคํธ๊ฐ ๋ฐ์ํ ์์์์ ์์ํ์ฌ ์์ ์์ (๋ถ๋ชจ, ์กฐ์ ์์)๋ก ์ ํ๋๋ ํ์์ด๋ค.
์๋ฅผ ๋ค์ด, <button>์ ํด๋ฆญํ๋ฉด ๊ทธ ํด๋ฆญ ์ด๋ฒคํธ๋ ๋ฒํผ โ ๋ถ๋ชจ <div> โ <body> ์์๋ก ์์ ์์๊น์ง ์ ๋ฌ๋๋ค.
์๋ ์ฝ๋๋ child ๋ฒํผ์ ํด๋ฆญํ๋ฉด ๋ถ๋ชจ ์์์ธ parent ๊น์ง ์ด๋ฒคํธ๊ฐ ์ ๋ฌ์ด ๋๋ ์์์ฝ๋์ด๋ค.
<div id="parent"> <button id="child">ํด๋ฆญํ์ธ์</button> </div> <script> document.getElementById('parent').addEventListener('click', function() { console.log('๐จ ๋ถ๋ชจ div ํด๋ฆญ๋จ!'); }); document.getElementById('child').addEventListener('click', function() { console.log('๐ถ ๋ฒํผ ํด๋ฆญ๋จ!'); }); </script>
์ด๋ ๊ฒ ๋ฒ๋ธ๋ง์ ํ์ฉํ๋ฉด ๋ถ๋ชจ ์์์์ ์์ ์์์ ์ด๋ฒคํธ๋ฅผ ๊ฐ์งํ ์ ์์ด ํจ์จ์ ์ด์ง๋ง ๋ฐ๋๋ก ๋ฒ๋ธ๋ง์ ๋ง์์ผ ํ๋ ๊ฒฝ์ฐ๋ ์๊ธด๋ค. ๋ฒ๋ธ๋ง์ ๋ง์ผ๋ ค๋ฉด event.stopPropagation()
์ ์ฌ์ฉํ๋ค.
document.getElementById('child').addEventListener('click', function(event) { event.stopPropagation(); // ๋ถ๋ชจ ์์๋ก ์ด๋ฒคํธ ์ ํ ์ฐจ๋จ console.log('๐ถ ๋ฒํผ ํด๋ฆญ๋จ! (๋ถ๋ชจ ์ด๋ฒคํธ ์คํ ์ ๋จ)'); });
9-2. ๋ฒ๋ธ๋ง(Bubbling)์ ๋ฐฉ์งํด์ผ ํ๋ ๊ฒฝ์ฐ

๋ชจ๋ฌ์ฐฝ์ ์์๋ก ๋ค ์ ์๋ค. ๋ชจ๋ฌ์ ๋ซ์ ๋ฐฉ๋ฒ์ผ๋ก๋ ๋ณดํต ๋ ๊ฐ์ง ๋ฐฉ๋ฒ์ด ์๋ค. '๋ซ๊ธฐ ๋ฒํผ'์ ํด๋ฆญํ๊ฑฐ๋, ๋ชจ๋ฌ ์ธ๋ถ๋ฅผ ํด๋ฆญํด์ ๋ซ์ ์ ์๋ค.
์ด ๋, ๋ชจ๋ฌ ์ธ๋ถ ํด๋ฆญ ์ ๋ซ๋ ๋์์ ์ค์ ํ๋ ค๋ฉด, ๋ชจ๋ฌ์ ์ธ๋ถ๋ฅผ ๊ฐ์ธ๊ณ ์๋ ๋ถ๋ชจ ์์์ธ #modal์ ํด๋ฆญ ์ด๋ฒคํธ๋ฅผ ์ค์ ํด์ผ ํ๋ค. ์ด ์ด๋ฒคํธ๋ก ๋ชจ๋ฌ ์ธ๋ถ๋ฅผ ํด๋ฆญํ๋ฉด alert('๋ชจ๋ฌ์ด ๋ซํ์ต๋๋ค.')๊ฐ ์คํ๋๊ณ ๋ชจ๋ฌ์ด ๋ซํ๋ ๋์์ด ์ํ๋๋ค. ํ์ง๋ง ๋ฌธ์ ๋ ๋ซ๊ธฐ ๋ฒํผ์ผ๋ก ๋ชจ๋ฌ์ ๋ซ์ ๋ ๋ฐ์ํ๋ค. ์ฌ๊ธฐ์, ๋ง์ฝ์ ๋ซ๊ธฐ ๋ฒํผ์ event.stopPropagation() ์ ๊ฑธ์ด ์ฃผ์ง ์์ผ๋ฉด ๋ฒ๋ธ๋ง์ด ์ผ์ด๋์ ๋ชจ๋ฌ์ด ๋ซํ๋ ํ์์ด ์ค๋ณต์ผ๋ก 2๋ฒ ์ํ์ด ๋๋ค.
<div id="modal"> <div id="modalContent"> <p>๋ชจ๋ฌ ๋ด์ฉ</p> <button id="closeButton">๋ซ๊ธฐ</button> </div> </div>
// ๋ชจ๋ฌ ์์ญ์ ํด๋ฆญํ๋ฉด ๋ชจ๋ฌ์ ๋ซ๋ ๋์ document.getElementById('modal').addEventListener('click', function() { alert('๋ชจ๋ฌ์ด ๋ซํ์ต๋๋ค.'); }); // ๋ซ๊ธฐ ๋ฒํผ ํด๋ฆญ ์ ๋ถ๋ชจ ์ด๋ฒคํธ ์ ํ ๋ฐฉ์ง document.getElementById('closeButton').addEventListener('click', function(event) { event.stopPropagation(); // ๋ถ๋ชจ ์ด๋ฒคํธ ์ ํ ๋ฐฉ์ง alert('๋ซ๊ธฐ ๋ฒํผ ํด๋ฆญ๋จ'); });
๋ submit ๋ฒํผ์ผ๋ก ํผ ์ ์ถ์ ํ ๋, ํ์ด์ง๊ฐ ๋ฆฌ๋ก๋๋๋ ๊ฒ์ ๋ฐฉ์งํ๋ ์ฉ๋๋ก event.preventDefault()๋ฅผ ์ฌ์ฉํ๋ค.
ํ์๊ฐ์
์ํฉ์ ์๊ฐ ํด ๋ณด์. ์ฌ์ฉ์๊ฐ ์ด๋ฆ, ์ด๋ฉ์ผ, ๋น๋ฐ๋ฒํธ ๋ฑ์ ์
๋ ฅํ๊ณ ์ ์ถ ๋ฒํผ์ ํด๋ฆญํ๋๋ฐ, ๋ฌธ์ ๊ฐ ์๊ฒจ ํ์ด์ง๊ฐ ์๋ก ๊ณ ์นจ๋๋ฉด ์ฌ์ฉ์๊ฐ ๋ค์ ๋ชจ๋ ์ ๋ณด๋ฅผ ์
๋ ฅํด์ผ ํ๋ ์ํฉ์ด ์๊ธด๋ค.
์๋ฅผ ๋ค์ด, ๋น๋ฐ๋ฒํธ๊ฐ ์๋ชป ์
๋ ฅ๋ ๊ฒฝ์ฐ, ํผ์ ์ ์ถํ๊ณ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ์ค์๊ฐ์ผ๋ก ํ์ํ๋ ค๋ฉด ํ์ด์ง๊ฐ ์๋ก ๊ณ ์นจ๋์ง ์์์ผ ํ๋ค. ๊ฐ๋ฐ์๋ ๋จ์ํ ์๋ชป๋ ํญ๋ชฉ์ ๋ํ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ํ๋ฉด์ ํ์ํด ์ฃผ๊ณ , ์ฌ์ฉ์๊ฐ ๊ธฐ์กด ์
๋ ฅ๊ฐ์ ๊ทธ๋๋ก ์ ์งํ๊ณ , ์์ ๋ง ํ ์ ์๋๋ก ํ๋ ๊ฒ์ด UX ์ธก๋ฉด์์ ํจ์ฌ ๋ ๊น๋ํ๋ค.
event.preventDefault()์ AJAX๋ฅผ ํจ๊ป ์ฐ๋ฉด ์๋ฒ์ ๋ฐ์ดํฐ๋ฅผ ๋น๋๊ธฐ์ ์ผ๋ก ๊ตํํ๋ฉด์ ํ์ด์ง ๋ฆฌ๋ก๋ ์์ด ๊ฒฐ๊ณผ๋ฅผ ์ฒ๋ฆฌํ ์ ์๊ธฐ ๋๋ฌธ์ ์ฌ์ฉ์๊ฐ ์
๋ ฅํ ๋ฐ์ดํฐ๋ฅผ ๋ค์ ์
๋ ฅํ๊ณ ๊ฒ์ฆ์ ๋ฐ์์ผ ํ๊ธฐ ๋๋ฌธ์ ๋ถํธํจ์ ๊ฒช์ง ์์๋ ๋๋ค.
(์ฐ๋ค ๋ณด๋ ๋ง์ด ์ด๋ ต๊ฒ ์ ํ๋๋ฐ ์๋ ์ฝ๋๋ก ํ์ธ ๊ฐ๋ฅํ๋ค)
document.getElementById('myForm').addEventListener('submit', function(event) { event.preventDefault(); // ํ์ด์ง ๋ฆฌ๋ก๋ ๋ฐฉ์ง // ๋น๋๊ธฐ ๋ฐ์ดํฐ ์ฒ๋ฆฌ ์์ (AJAX) const formData = new FormData(this); fetch('/submit', { method: 'POST', body: formData, }) .then(response => response.json()) .then(data => { console.log('ํผ ๋ฐ์ดํฐ ์ ์ก ์ฑ๊ณต', data); }) .catch(error => { console.error('ํผ ์ ์ถ ์คํจ', error); }); });
9-3. ์บก์ฒ๋ง(Capturing)์ด๋?

๋ฐ๋๋ก, ์ด๋ฒคํธ๊ฐ ์ต์์ ์์์์ ์์ํ์ฌ ํ์ ์์๋ก ์ ๋ฌ๋๋ ๋ฐฉ์์ ์บก์ฒ๋ง(Capturing)์ด๋ผ๊ณ ํ๋๋ฐ ๋ฐ๋๋ก ๋ถ๋ชจ์ div์ click ์ด๋ฒคํธ๊ฐ ์คํ๋๋ฉด, ์์์ ์ด๋ฒคํธ๋ ์คํ๋๋ ๊ฒ์ด๋ค. ํ์ง๋ง ์บก์ฒ๋ง์ ์ ์ฌ์ฉ๋์ง ์๋๋ค. ์๋ํ๋ฉด ๊ธฐ๋ณธ์ ์ผ๋ก ๋ธ๋ผ์ฐ์ ๋ ๋ฒ๋ธ๋ง์ ์ฐ์ ์ฌ์ฉํ๋ค. ์ด ๋ถ๋ถ์ ์ ํ์ฉ๋์ง ์๋ ๋ถ๋ถ์ด๋ฏ๋ก ์ฌ๊ธฐ๊น์ง๋ง ์ ๋ฆฌํ๋ค.
9-4. ํ๊ฒ(target)์ด๋?
target์ ์๋ฐ์คํฌ๋ฆฝํธ ์ด๋ฒคํธ ๊ฐ์ฒด์ ์์ฑ์ผ๋ก, ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ ์ค์ DOM ์์๋ฅผ ์ฐธ์กฐํ๋ค. ์ฃผ๋ก ์ด๋ฒคํธ ํธ๋ค๋ฌ์์ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ ๋์ ์์๋ฅผ ์๊ธฐ ์ํด ์ฌ์ฉ๋๋ ์์ฑ์ด๋ค.
์๋ ์ฝ๋์์event.target์ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ ์์๋ฅผ ๊ฐ๋ฆฌํจ๋ค. ๊ทธ๋์ myButton์ ํด๋ฆญํ๋ฉด event.target์ ๋ฐ๋ก ํด๋ฆญ๋ ๋ฒํผ ์์๋ฅผ ๋ฐํํ๋ค.
document.getElementById('myButton').addEventListener('click', function(event) { console.log(event.target); // ํด๋ฆญํ ์ค์ ์์๊ฐ ์ถ๋ ฅ๋จ });
์ฌ๋ฌ ์์ ์์๊ฐ ์์ ๋, ์ด๋ฒคํธ ์์์ด ์ผ์ด๋์ ๋ถ๋ชจ ์์์์ ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํ ์ ์๋ค. ์ด๋ event.target์ ์ฌ์ฉํ์ฌ ์ค์ ํด๋ฆญ๋ ์์ ์์๋ฅผ ํ์ธํ ์ ์๋ค.
document.getElementById('parent').addEventListener('click', function(event) { if (event.target && event.target.matches('button')) { alert('๋ฒํผ์ด ํด๋ฆญ๋จ!'); } });
10. ์ฐธ๊ณ ์๋ฃ
1. chatGPT์ ๊ถ๊ธํ ๋ถ๋ถ์ ๋ฌผ์ด ๊ฐ๋ฉด์ ํฌ์คํ
์ ์์ฑํ์
2. ํฌ์คํ
์์ฑ์ ๋์์ ์ฃผ์ ๋ธ๋ก๊ทธ
[Javascript] ๋ง์ฐ์ค ์ด๋ฒคํธ / ๋๋๊ทธ ์ค ๋๋กญ (Drag and drop)
๐ก ์ด ํฌ์คํ ์ ์ด๋ฒคํธ ๋ง์ฐ์ค ์ด๋ฒคํธ ์ค ๋๋๊ทธ ์ค ๋๋กญ ๋ํด ๊ณต๋ถํ๋ฉฐ ์ ๋ฆฌํ ๋ด์ฉ์ ๋๋ค. ํน์ฌ๋ ์ผ๋ถ ์ฌ๋ฐ๋ฅด์ง ์์ ์ ๋ณด๊ฐ ์์ ์์ ์ง์ ํด์ฃผ์๋ฉด ์ ์ ํ ๋กํ๊ฒ ์ต๋๋ค.๋ง์ฐ์ค ์ด๋ฒคํธ์
velog.io
[JS-์ค๊ธํธ-์ด๋ฒคํธ] 3. ๋ง์ฐ์ค ์ด๋ฒคํธ
์ฌ๋๋ค์ด ์ปดํจํฐ์ ์ํธ ์์ฉํ๋ ๊ฐ์ฅ ์ผ๋ฐ์ ์ธ ๋ฐฉ๋ฒ ์ค ํ๋๋ ๋ง์ฐ์ค๋ก ์๋ ค์ง ํฌ์ธํ ์ฅ์น๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ๋๋ค. ๋ง์ฐ์ค ์ด๋ฒคํธ ๋ง๋๋ณด๊ธฐ JavaScript์์ ๋ง์ฐ์ค๋ฅผ ๋ค๋ฃจ๋ ์ฃผ๋ ๋ฐฉ๋ฒ์ ์ด๋ฒคํธ
cpro95.tistory.com
์ด๋ฒคํธ ๋ฒ๋ธ๋ง๊ณผ ์ด๋ฒคํธ ์บก์ฒ๋ง, ์ด๋ฒคํธ ์์
๋ค์ ์ฝ๋๋ฅผ ๋ณด์.๋ฒํผ์ ํด๋ฆญ ์ด๋ฒคํธ๋ฅผ ํ ๋นํ๊ณ , ํด๋ฆญ๋์์ ๋ console.log๊ฐ ์ถ๋ ฅ๋๋๋ก ํ์๋ค.button์ ํด๋ฆญํ๋ฉด ์ด๋ค ์ผ์ด ๋ฒ์ด์ง๊น?image๋ฒํผ์ ํด๋ฆญ ์ด๋ฒคํธ๊ฐ ์คํ๋๊ณ , ์ฝ์์๋ 'button'์ด ์ถ
velog.io