DOM 이벤트는 웹 페이지 내의 특정 요소에 대한 상호작용이나 생명주기의 변화를 나타내는데, 이를 통해 JavaScript는 사용자의 행동에 반응하거나 다른 이벤트에 응답할 수 있다. 예를 들면, 사용자가 버튼을 클릭했을 때 특정 동작을 수행하는 것과 같은 상호작용을 구현할 수 있다.
간단한 예제로, 버튼의 클릭 이벤트에 반응하는 코드는 다음과 같다.
document.querySelector('button').addEventListener('click', function(event) {
alert('버튼이 클릭되었습니다!');
});
이 코드는 페이지 내의 버튼 요소를 선택하고, 해당 버튼이 클릭될 때마다 경고 창을 표시하는 이벤트 리스너를 추가한다.
이벤트는 웹 애플리케이션의 동적인 특성을 구현하는 데 필수적이다. 사용자의 입력을 처리하거나 다른 요소와 상호 작용하기 위해 다양한 이벤트 타입과 메소드를 활용할 수 있다.
'EventListener'는 웹에서 일어나는 다양한 동작이나 변화, 즉 "이벤트"에 반응하기 위해 사용되는 메커니즘이다. 웹 페이지 내의 특정 요소에 대한 사용자의 동작(예: 클릭, 키보드 입력, 마우스 움직임 등)이나, 브라우저의 특정 변화(예: 문서 로드 완료, 화면 크기 변화 등)에 반응하여 특정 코드나 함수를 실행할 수 있게 한다.
'EventListener'를 사용하는 방법은 대체로 두가지가 있다.
<button onclick="myFunction()">Click me</button>
document.querySelector('button').addEventListener('click', myFunction);
target.addEventListener(type, listener[, options]);
이벤트 리스너를 통해 이벤트가 발생할 때마다 해당 이벤트에 대한 정보를 포함하는 이벤트 객체가 콜백 함수로 전달된다. 이 객체를 사용하여 이벤트의 세부 사항을 얻거나, 이벤트의 기본 동작을 방지하거나, 이벤트의 전파를 중단할 수 있다.
마지막으로, 필요없어진 이벤트 리스너는 메모리 관리와 성능 향상을 위해 removeEventListener 메서드를 사용하여 제거해야 한다.
Event 객체는 DOM 이벤트 리스너에 의해 생성되고 전달되며, 해당 이벤트에 관한 정보를 제공하고, 이벤트의 기본 동작을 제어하는 메서드를 포함하고 있다.
Event 객체의 주요 속성과 메서드는 다음과 같다.
target: 이벤트가 시작된 DOM 요소를 참조한다. 예를 들어, 버튼을 클릭하면 event.target은 해당 버튼 요소를 참조하게 된다.
type: 발생한 이벤트의 유형을 나타내는 문자열이다. 예를 들어, 클릭 이벤트의 경우 type 값은 "click"이다.
currentTarget: 현재 이벤트 리스너가 부착된 DOM 요소를 참조한다. event.target과 다른 점은, 이벤트 버블링 중에 여러 리스너가 호출될 때 currentTarget이 바뀌는 것이다.
preventDefault(): 이벤트의 기본 동작을 중단시킨다. 예를 들어, 폼 제출 이벤트에서 preventDefault()를 호출하면 폼 제출을 중지할 수 있다.
stopPropagation(): 현재 이벤트의 전파를 중단시킨다. 이 메서드를 호출하면 이벤트 버블링이나 캡처링이 중단된다.
bubbles: 이벤트가 버블링되는지 여부를 나타내는 부울 값이다.
cancelable: 이벤트의 기본 동작이 중단 가능한지 여부를 나타내는 부울 값이다. 이 값이 true일 때 preventDefault()를 사용할 수 있다.
detail: 마우스 클릭 이벤트에서 사용자가 클릭한 횟수를 나타내거나, UIEvent 객체의 경우 추가 정보를 제공하는 속성이다.
특정 이벤트 유형에 따라, Event 객체는 추가적인 속성과 메서드를 포함할 수 있다. 예를 들어, MouseEvent 객체는 클릭 좌표나 사용된 마우스 버튼에 관한 정보를 제공하는 추가 속성을 가지고 있다.
이벤트 객체를 사용하면 이벤트에 대한 상세한 정보를 얻을 수 있으며, 이를 통해 더욱 정교한 이벤트 처리 로직을 구현할 수 있다.
const buttonElement = document.querySelector('.btn2');
buttonElement.addEventListener('click', (event) => {
let val;
val = event.target;
val = event.target.className;
val = event.target.classList;
val = event.type;
// 윈도우로부터의 거리 좌표
val = event.clientY;
// 요소로부터의 거리 좌표
val = event.offsetY;
console.log(event);
})
const buttonElement = document.querySelector('.btn2');
이 줄에서, 'document.querySelector('.btn2')'를 사용하여 HTML 문서에서 '.btn2'라는 클래스를 가진 첫 번째 요소를 선택하고, 이를 'buttonElement'라는 상수에 할당한다. 즉, '.btn2' 클래스를 가진 버튼 요소에 대한 참조를 얻는다.
buttonElement.addEventListener('click', (event) => {
// ... 내부 로직 ...
});
'buttonElement' 'click' 이벤트 리스너를 추가한다. 버튼이 클릭될 때마다, 제공된 콜백 함수가 호출된다. 이 콜백 함수는 이벤트 객체 event를 매개변수로 받는다.
val = event.target;
여기에서 event.target은 클릭된 DOM 요소를 참조한다. 이 경우, 버튼 요소 자체가 된다.
val = event.target.className;
event.target.className은 클릭된 요소의 클래스 이름 문자열을 반환한다.
val = event.target.classList;
event.target.classList는 클릭된 요소의 클래스 이름들을 DOMTokenList 형태로 반환한다. 이를 통해 클래스 목록을 배열과 유사하게 다룰 수 있다.
val = event.type;
event.type은 발생한 이벤트의 유형을 나타내는 문자열을 반환한다. 여기서는 "click"이 된다.
val = event.clientY;
'event.clientY'는 클릭된 지점의 세로 좌표를 반환한다. 이 값은 전체 브라우저 창의 최상단을 기준으로 한다.
val = event.offsetY;
event.offsetY는 클릭된 지점의 세로 좌표를 반환한다. 하지만 이 값은 클릭된 요소의 최상단을 기준으로 한다.
console.log(event);
마지막으로, 전체 이벤트 객체를 콘솔에 로깅한다. 이를 통해 이벤트 객체의 모든 속성과 메서드에 대한 정보를 볼 수 있다.
요약하면, 이 코드는 .btn2 클래스를 가진 버튼이 클릭될 때 발생하는 이벤트에 대한 정보를 캡쳐하고, 콘솔에 출력하는 기능을 구현하고 있다.
콜백 함수(callback function)는 다른 함수에 인자로 전달되는 함수이다. 주로, 어떤 작업이 완료된 후에 실행될 함수를 지정할 때 사용한다. 이렇게 하면, 특정 작업의 완료 시점을 알지 못해도 해당 작업이 완료될 때 원하는 동작을 수행할 수 있다.
콜백 함수는 비동기 프로그래밍에서 특히 중요한 개념이다. 비동기 작업이 완료될 때마다 특정 함수를 실행하도록 예약할 수 있기 때문이다.
예시를 통해 콜백 함수의 작동 방식을 이해해 보자.
function greetUser(name, callback) {
const greeting = `Hello, ${name}!`;
callback(greeting); // 콜백 함수 호출
}
greetUser('Alice', function(message) {
console.log(message);
});
위 예시에서 'greetUser' 함수는 두 개의 매개변수를 받는다. name과 callback
.
'greetUser' 함수는 사용자에게 인사를 하는 메시지를 생성한 후, 콜백 함수를 호출하여 생성된 메시지를 전달한다. 따라서, 위 코드를 실행하면 콘솔에 "Hello, Alice!"가 출력된다.
이렇게 콜백 함수를 사용하면, 함수의 실행이 끝난 후 특정 동작을 수행하도록 코드를 구조화할 수 있다.
하지만 콜백 함수를 과도하게 중첩하여 사용하면 코드가 복잡해지고 가독성이 떨어지는 "콜백 지옥(callback hell)"이 발생할 수 있다. 이런 문제를 해결하기 위해 Promise, async/await와 같은 모던 자바스크립트의 비동기 처리 패턴이 도입되었다.