이벤트란?
프로그래밍을 하다 보면 이벤트(Event)라는 용어를 자주 듣게 됩니다. 이벤트는 웹 페이지에서 발생하는 각종 사건이나 상호작용을 가리키는데, 이러한 일이 일어났을 때 브라우저가 신호를 보내고 우리가 등록한 코드가 실행됩니다.

버튼을 클릭하거나 키보드를 통해 입력하는 것처럼 사용자가 이벤트를 발생시킬 수도 있고, 페이지가 로드되면서 어플리케이션이 스스로 이벤트를 발생시킬 수도 있습니다.
웹 페이지 안에서 이런 이벤트들은 이벤트 핸들러를 통해서 처리할 수 있습니다.
이벤트 핸들러는 이벤트에 대응하여 이벤트가 발생했을 때 수행할 동작을 하는 함수입니다.
이벤트 리스너라고도 합니다.
예를 들어 사용자가 버튼을 클릭하면 브라우저는 "클릭 이벤트"라는 신호를 발생시키고, 이에 반응하여 우리가 지정한 함수(이벤트 핸들러)가 실행될 수 있습니다.
이벤트 객체란?
이벤트 객체는 이벤트가 발생하면 브라우저는 이벤트에 대한 정보를 담은 객체를 전달하는데 이를 이벤트 객체라고 합니다.

일반적으로 이벤트 핸들러 함수를 정의할 때는 event , e 라는 매개변수를 넣습니다.
(넣지 않아도 됩니다. 하지만 이벤트 헨들러 함수는 항상 첫 번째 매개변수를 이벤트 객체로 인식합니다)
이 변수가 바로 이벤트 객체입니다.
이벤트 객체에는 해당 이벤트와 관련된 다양한 정보가 들어 있습니다.
예를 들어서 event.target 속성은 이벤트가 발생한 대상 element를 가리키빈다.
키보드 이벤트라면 어떤 키를 눌렀는지 알려주는 key 속성이 들어있는 KeyBoradEvent 객체가 전달되고, 마우스 이벤트의 경우에는 마우스의 좌표나 버튼 정보 등이 들어있는 MouseEvent 객체가 전달됩니다.
이러한 이벤트 객체 덕분에 이벤트 핸들러 함수 안에서 어떤 일이 일어났는지 잘 파악하고 처리할 수 있습니다.
이벤트 종류 소개
자바스크립트에서 다룰 수 있는 이벤트의 종류는 매우 많습니다.
- 사용자의 입력
- 브라우저의 상태 변화
- 사용자의 클릭
- 사용자의 마우스 위치
- …
마우스 이벤트
마우스 이벤트는 마우스를 이용한 사용자의 동작과 관련된 이벤트 입니다.
이벤트
|
설명
|
click
|
사용자가 마우스로 요소를 클릭할 때 발생 (버튼을 눌렀다가 떼었을 때)
|
dblclick
|
요소를 더블 클릭할 때 발생
|
mouseover
|
마우스 커서를 요소 위에 올렸을 때 발생
|
mouseout
|
요소 위에 있던 마우스 커서가 밖으로 벗어났을 때 발생
|
- mousedown: 마우스 버튼을 누른 순간
- mouseup: 누른 마우스 버튼을 떼는 순간
- mousemove: 마우스 커서의 움직임
버튼을 클릭하면 새로운 탭을 열거나 특정 요소의 색을 바꾸는 동작들을 할 수 있겠습니다.
키보드 이벤트
키보드를 입력할 때 발생하는 이벤트입니다. 폼에 글자를 입력하거나 게임에서 키 조작을 처리할 때 활용됩니다.
대표적으로는 아래 것들이 있습니다.
이벤트
|
설명
|
keydown
|
사용자가 키보드를 눌렀을 때 발생 (키를 누르는 순간 한 번 발생)
|
keyup
|
눌렀던 키를 떼는 순간 발생
|
keypress
|
키를 누를 때 발생하는 이벤트 (문자 입력과 관련된 키에서 동작, 현재는 keydown으로 대체됨)
|
키보드 이벤트의 이벤트 객체는 KeyBoardEvent이고, 여기에 어떤 키를 눌렀는지 알려주는 (key 등) 정보가 들어있습니다. 예를 들어서 event.key를 통해서 사용자가 눌린 키 값을 알아 낼 수 있습니다. 이를 활용하면 엔터 키를 감지해 폼을 전송하거나 할 수 있겠습니다.
폼 이벤트
폼과 관련된 요소에서 발생하는 이벤트입니다. 사용자 입력이나 폼 제출 등 사용자 입력 양식에 특화된 이벤트들입니다. 주요한 폼 이벤트들은 아래와 같습니다.
이벤트
|
설명
|
submit
|
사용자가 폼을 제출할 때 발생 (<form> 요소에서 사용, 폼 데이터 검증 및 전송 처리)
|
change
|
입력 필드(<input>, <select> 등)의 값이 변경될 때 발생 (체크 박스 상태 변경, 텍스트 입력 후 포커스를 잃었을 때 등)
|
focus / blur
|
입력 요소가 포커스를 받을 때(focus), 포커스를 잃을 때(blur) 발생 (UI에서 입력 필드 강조나 검증 메시지 표시할 때 사용)
|
폼 이벤트들은 사용자 입력을 검증하거나 실시간으로 반응하는 양식(form) 관련 기능을 만들 때 꼭 알아야 하는 이벤트들입니다.
이벤트 사용 방법 소개
이벤트를 처리하려면 요소에 이벤트 리스너를 등록해야합니다.
이벤트 리스너는 이름처럼 특정 이벤트가 발생하기를 경청하고 있다가, 해당 이벤트가 발생하면 등록된 이벤트 리스너 함수를 실행합니다.
이벤트를 등록하는 방법은 두 가지가 있습니다.
- addEventListener 메소드 사용
- HTML 태그에 직접 이벤트 속성 추가
가장 많이 사용하고 권장되는 방법은 addEventListener 메소드를 사용하는 것입니다.
addEventListener 사용해서 이벤트 등록하기
요소노드.addEventListener("이벤트명", 이벤트헨들러함수)
- 첫 번째 인자로 문자열 이벤트 타입명을 지정합니다. 클릭이면 “click” , 키보드 입력이면 "keydown” 을 입력합니다.
- 두 번째 인자로는 이벤트 발생 시 호출한 핸들러 함수를 전달합니다.
이 함수는 해당 이벤트가 일어날 때 실행될 코드 블럭입니다.
예를 들어서 버튼 요소에 클릭 이벤트 헨들러 등록하고 싶다면 아래와 같이 합니다.
const btn = document.querySelector('button');
btn.addEventListener('click', function(event) {
console.log('버튼이 클릭되었습니다!');
});
이제 브라우저는 해당 버튼을 사용자가 클릭하는 순간 우리의 함수가 호출되어 “버튼이 클릭되었습니다!” 라는 메세지를 콘솔에 출력합니다.
한 요소에 여러 개의 리스너를 등록할 수도 있습니다. addEventListener를 같은 요소에 여러번 호출하면 각각의 핸들러가 모두 실행됩니다.
또한 addEventListener를 통해서 등록한 리스너는 나중에 다시 제거할 수도 있습니다. 필요에 따라서 removeEventListener를 호출해서 특정 핸들러의 동작을 그만두게 할 수 있습니다.
HTML 속성으로 이벤트 등록
이벤트를 등록하는 다른 방법으로는 HTML 태그에 이벤트를 직접 작성하는 방식이 있습니다.
예를 들어서 <button onclick="alert('Hello');">클릭</button> 처럼 요소의 attribute 노드 로 onclick 를 달아서 클릭 시 실행할 자바스크립트 코드를 직접 넣는 방법입니다. 옛날에는 이런 방식을 많이 사용했지만 지금은 권장되는 방법은 아닙니다.
(그래도 배우는 이유가 있는데 React 배울 때 알 수 있습니다)
간단한 예를 들어보겠습니다.
<button onclick="changeColor()">배경 색상 변경</button>
그리고 자바스크립트 코드를 changeColor 함수를 정의합니다.
<script>
function changeColor() {
document.body.style.backgroundColor = 'skyblue';
}
</script>
이렇게 하면 사용자가 버튼을 클릭할 때마다 onclick 속성에 지정된 changeColor() 함수가 호출되어 페이지 배경 색상이 하늘색으로 바뀝니다.
동작 자체는 잘 되지만 HTML과 자바스크립트 코드가 혼재되어서 유지보수가 어렵습니다. 그리고 가독성도 아주 별로에요.
그래서 이런 방법은 지양하는 것이 좋습니다.
이벤트 사용 실습
이제 이론을 봤으니, 간단한 실습 예제로 이벤트를 사용하는 방법을 확인해봅시다.
버튼을 클릭하면 텍스트를 바꾸고, 이벤트 객체의 정보를 콘솔에 출력하는 예제를 만들어 볼게요.
같이 해봅시다!
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<title>이벤트 실습</title>
</head>
<body>
<button id="myButton">눌러보세요</button>
<p id="message">버튼을 아직 누르지 않았습니다.</p>
<script>
// 여기에 자바스크립트 코드를 작성합니다!
</script>
</body>
</html>
우선 실습을 하기 전에 이벤트 객체를 console.log 로 찍어보고 넘어가겠습니다.
그리고 event 객체를 같이 뒤져봅시다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>이벤트 실습</title>
</head>
<body>
<button id="myButton">눌러보세요</button>
<p id="message">버튼을 아직 누르지 않았습니다.</p>
<script>
const btn = document.getElementById("myButton");
btn.addEventListener("click", (event) => {
console.log(event);
});
</script>
</body>
</html>
이제 버튼을 누르면 p태그의 내용이 바뀌도록 해보겠습니다.
- 버튼 클릭해서 msg 요소 텍스트 바꾸기
- 버튼 클릭으로 자기 요소의 배경색 바꾸기
위 코드에서는 HTML에 하나의 버튼과 하나의 <p> 요소가 있습니다. 자바스크립트에서 getElementById로 이 요소들을 가져와 변수 btn과 msg에 저장한 후, btn에 대해 click 이벤트 리스너를 등록했습니다.
이벤트 핸들러 함수 내부를 보면, 먼저 msg 요소의 텍스트를 "버튼이 눌렸습니다!"로 바꾸고 있습니다.
그 다음 e.target.style.backgroundColor = 'yellow' 코드를 통해 이벤트 객체 e의 target 속성, 즉 클릭된 요소 자체의 배경색을 노란색으로 변경했습니다. 마지막으로 console.log를 사용해 이벤트 객체 e의 type 속성을 출력했는데, 클릭 이벤트의 경우 "click"이라는 문자열이 들어있어 콘솔에 이벤트 타입: click이라고 표시됩니다. 이 페이지를 실제로 열고 버튼을 누르면, 페이지 내 텍스트가 "버튼이 눌렸습니다!"로 바뀌고 버튼의 배경색도 노란색으로 변합니다.
개발자 콘솔을 열어보면 "이벤트 타입: click"이라는 로그가 찍힌 것을 확인할 수 있습니다. 이처럼 이벤트 리스너 내부에서 이벤트 객체 e를 활용하면 어떤 요소에서 이벤트가 발생했는지(e.target), 어떤 종류의 이벤트인지(e.type) 등 유용한 정보를 얻어 활용할 수 있습니다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<title>이벤트 실습</title>
</head>
<body>
<button id="myButton">눌러보세요</button>
<p id="message">버튼을 아직 누르지 않았습니다.</p>
<script>
const btn = document.getElementById('myButton');
const msg = document.getElementById('message');
// 버튼에 클릭 이벤트 리스너 등록
btn.addEventListener('click', function(e) {
// 이벤트 핸들러 내부
msg.textContent = '버튼이 눌렸습니다!'; // <p> 태그의 내용 변경 (text node를 변경)
e.target.style.backgroundColor = 'yellow'; // 이벤트 발생 대상(btn)의 배경색 변경
console.log('이벤트 타입:', e.type); // 콘솔에 이벤트 타입 출력 (예: "click")
});
</script>
</body>
</html>
이벤트 버블링 막기
마지막으로 알아볼 개념은 이벤트 버블링(Event Bubbling)과 이를 제어하는 방법입니다.
이벤트 버블링이란 부모-자식 관계에 있는 요소에서 이벤트가 발생할 때의 전파 특성을 말합니다.
간단히 말해, 어떤 요소에서 이벤트가 발생하면 그 이벤트가 해당 요소뿐만 아니라 부모 요소에도 전달되어 올라가는 현상을 이벤트 버블링이라고 합니다. 예를 들어 설명해볼게요. <div> 안에 <button>이 있는 구조에서 <div>와 <button> 모두 클릭 이벤트 핸들러를 등록했다고 해봅시다.
이 경우 사용자가 버튼을 클릭하면 먼저 버튼의 클릭 핸들러가 실행된 후, 이벤트가 상위 요소로 전파되어 결국 감싸고 있는 <div>의 클릭 핸들러도 이어서 실행됩니다.
이렇게 자식에서 발생한 이벤트가 부모로 전파되는 것이 버블링입니다 (마치 물속 거품이 아래에서 위로 올라가는 것과 비슷한 이미지라서 bubbling이라 부릅니다). 하지만 모든 경우에 이벤트 버블링이 바람직한 것은 아닙니다.
경우에 따라서는 버블링 때문에 원치 않는 부수 효과가 생기기도 합니다. 앞의 예시에서 사용자가 버튼만 클릭했는데 부모 <div>에 연결된 동작까지 실행되는 것은 의도와 다를 수 있겠지요.
이럴 때는 이벤트 전파를 중단시킬 수 있습니다.
방법은 매우 간단한데, 이벤트 핸들러 함수 내부에서 event.stopPropagation() 메서드를 호출하면 됩니다. stopPropagation()을 호출하면 해당 이벤트는 더 이상 상위 요소로 전파되지 않고 그 자리에서 전파가 멈춥니다.
이벤트 버블링 막기 실습
이론으로 알려드렸던 상황을 직접 구현해보겠습니다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<title>이벤트 실습</title>
</head>
<body>
<div id="parent" style="padding: 20px; background-color: #ddd">
<button id="child">버튼</button>
</div>
<script>
// 여기에 자바스크립트 코드를 작성합시다!
</script>
</body>
</html>
위 코드에서 회색 배경을 가진 <div id="parent">와 그 안에 <button id="child">가 있습니다.
parent <div>에는 클릭할 때 alert로 "부모 요소 DIV 클릭 이벤트 발생!"이 뜨도록 핸들러를 달았고, child 버튼에도 "자식 요소 BUTTON 클릭 이벤트 발생!" 경고창을 띄우는 핸들러를 달겠습니다. 이 상태로 페이지에서 버튼을 클릭하면 어떻게 될까요?
먼저 버튼의 핸들러가 실행되어 "자식 요소 BUTTON 클릭 이벤트 발생!" 얼럿이 뜨고, 그 다음 바로 부모 <div>의 핸들러도 실행되어 "부모 요소 DIV 클릭 이벤트 발생!" 얼럿이 나타납니다.
즉, 버튼 클릭 하나로 두 개의 핸들러가 순차적으로 호출된 것이죠.
이것이 이벤트 버블링으로 인한 효과입니다.
저는 하나의 요소만 클릭되게 하고 싶어서 이벤트 버블링에 의해서 두 요소가 클릭된 것으로 간주됩니다.
버튼의 클릭 이벤트가 상위 <div>로 전파되었기 때문입니다.
이제 버튼 핸들러에서
e.stopPropagation()
줄의 주석을 해제하고 다시 버튼을 클릭해보세요.
이번에는 버튼의 핸들러만 실행되고 부모 <div>의 핸들러는 실행되지 않습니다.
stopPropagation()
을 호출함으로써 버튼 클릭 이벤트가 부모로 퍼져나가는 것을 막았기 때문입니다.
이렇게 하면 사용자가 의도하지 않은 상위 요소의 동작이 발생하는 것을 예방할 수 있습니다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<title>이벤트 실습</title>
</head>
<body>
<div id="parent" style="padding: 20px; background-color: #ddd">
<button id="child">버튼</button>
</div>
<script>
const parent = document.getElementById("parent");
const child = document.getElementById("child");
parent.addEventListener("click", function () {
alert("부모 요소 DIV 클릭 이벤트 발생!");
});
child.addEventListener("click", function (e) {
alert("자식 요소 BUTTON 클릭 이벤트 발생!");
//e.stopPropagation(); // ← 이 줄을 활성화하면 버블링을 막습니다.
});
</script>
</body>
</html>
'웹' 카테고리의 다른 글
[Web] DOM과 브라우저의 렌더링 프로세스 (0) | 2025.07.24 |
---|