▼ HTML 문서
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="content" class="btns">
<button id="myBtn">JS Hi</button>
<button onclick="console.log('Hello')">HTML Hello</button>
</div>
<script src="index.js"></script>
</body>
</html>
버튼 클릭 이벤트에서 이벤트 핸들러를 등록하는 두 가지 방법이 있다고 했을 때, - Link
- Dom 요소 접근하여 onclick 프로퍼티 활용
- HTML 태그에 onclick 속성 활용
또한 HTML 태그에서 직접 이벤트를 다루는 일은 잘 사용하지 않으며 문제도 많아 잘 쓰이지 않는다고 했다.
다시한번 onclick 동작 구조를 살펴보기위해 각 버튼에 적용해보자면
//이벤트 핸들러 등록하기
let btn = document.querySelector("#myBtn");
btn.onclick = function () {
console.log("Hi");
};
이렇게 등록한 이벤트 핸들러가 잘 동작하는 것을 확인할 수 있다.
하지만 onclick 프로퍼티를 활용하는 방법도 단점이 있는데
innerHTML이나 className같은 프로퍼티를 활용할 때도
프로퍼티에 어떤 값을 할당하는 방식은 기존에 있던 값을 덮어쓰는 형태로 동작하기 때문에
기존에 있는 값을 유지하면서 일부만 수정하기엔 어렵다.
onclick 프로퍼티도 아래와 같이 새로운 이벤트 핸들러를 할당하게 되면
기존의 값을 덮어쓰기로 인해 결과는 'Hi' 문자열은 사라지고 'HiHi로 출력되는 것을 화인할 수 있다.
//이벤트 핸들러 등록하기
let btn = document.querySelector("#myBtn");
btn.onclick = function () {
console.log("Hi");
};
btn.onclick = function () {
console.log("HiHi");
};
그러다보면 중요한 이벤트를 덮어버리는 최악의 상황이 나올뿐만 아니라
여러개의 이벤트 핸들러를 다룰 수도 없다는 큰 단점이 있다는 것이다.
이러한 문제를 해결하기 위해서 하나의 이벤트 핸들러 안에 여러개의 이벤트 핸들러를 넣는 방법이 있긴 하지만
//이벤트 핸들러 등록하기
let btn = document.querySelector("#myBtn");
/*
btn.onclick = function () {
console.log("Hi");
};
btn.onclick = function () {
console.log("HiHi");
};
*/
function event1() {
console.log("Hi");
}
function event2() {
console.log("HiHi");
}
btn.onclick = function () {
event1();
event2();
};
이마저도 중간에 새로운 이벤트를 추가하거나
혹은 제거해야하는 상황이 오면 대처하기 어렵고
간단한 이벤트가 아닌 리턴 값이 오가는 중요한 이벤트가 있을 경우
그 리턴 값도 다뤄야하는 매우 복잡한 문제가 생기게 된다.
그래서 onclick 프로퍼티를 활용하지 않고 이벤트 핸들러를 등록하는 방법이 있다.
addEventListener 메소드
이벤트 핸들러를 등록할 때 가장 선호하는 방식이며
이벤트 핸들러를 등록하고 싶은 요소에 'addEventListener'를 호출하는데
첫 번째 파라미터로 이벤트 타입을 문자열로 전달하고
두 번째 파라미터로 이벤트 핸들러를 전달한다.
//이벤트 핸들러 등록하기
let btn = document.querySelector("#myBtn");
function event1() {
console.log("Hi");
}
function event2() {
console.log("HiHi");
}
//elem.addEventListner[event, handler]
btn.addEventListener("click", event1);
btn.addEventListener("click", event2);
이렇게 메소드를 여러번 호출하게 되면
하나의 요소에 여러 개의 독립적인 이벤트 핸들러를 등록할 수 있다.
또한 이렇게 등록한 이벤트는 개별적으로 제거할 수 있다.
removeEventListener 메소드
add로 등록할 떄와 똑같이 먼저 event 타입을 문자열로 전달하고
등록할 때 전달했던 이벤트 핸들러를 두 번째 파라미터로 전달하게 되면
해당 이벤트 핸들러가 삭제되는 방식이다.
//이벤트 핸들러 등록하기
let btn = document.querySelector("#myBtn");
function event1() {
console.log("Hi");
}
function event2() {
console.log("HiHi");
}
//elem.addEventListner[event, handler]
btn.addEventListener("click", event1);
btn.addEventListener("click", event2);
//elem.removeEventListner[event, handler]
btn.removeEventListener("click", event2);
이렇게 event2는 등록되었다가 다시 삭제되었기 때문에
'JS click!' 버튼을 클릭하면 event1만 동작하므로 'Hi'만 출력되는 것을 확인할 수 있다.
▼ 이벤트 핸들러 사용시 주의해야할 점
※ 이벤트를 삭제할 때 반드시 등록할 때 사용했던 핸들러를 그대로 전달해야한다
이게 무슨말이냐면 이벤트를 등록할 때 핸들러를 전달하는 부분에서
함수를 바로 작성할 수 있기 때문에 ▼
똑같이 작성한다고 하면 정상적으로 삭제될 것처럼 보이지만 전혀 아니다. ▼
모양은 똑같지만 서로 다른 함수이기 때문에 이벤트 핸들러가 정상적으로 삭제되지 않는다.
그래서 이벤트 핸들러를 삭제해야 한다면
반드시 이벤트를 등록할 때 외부에 함수를 만들어서
해당 함수의 이름으로 핸들러를 전달해 주면된다.
※이벤트 핸들러 부분에는 그냥 함수 이름만 전달해야한다.
예를들면 핸들러에 아래와 같이 소괄호를 붙여주는 경우가 있는데
하지만 이렇게 하게되면 핸들러 부분을 해석 할 때 함수를 그대로 호출해버려서
함수를 호출한 리턴 값, 즉 이 경우엔 리턴 값이 없는, 비어있는 상태이기에
undefiend가 두 번째 파라미터로 전달돼버려서 이벤트 핸들러가 등록되지 않게 된다.
한번 실행해보면 호출한 값은 'Hi'로 잘 출력이 되는데
버튼을 클릭해보면 아무런 동작도 하지 않는 것을 확인 할 수 있을 것이다.
이렇게 addEventListener 메소드를 쓰면
하나의 요소에 여러 이벤트 핸들러를 자유롭게 설정할 수 있으며
사용하면서 주의해야될 부분만 잘 기억해두면 사용할 때 난감한 상황을 잘 해결할 수 있을 것이다.
▼ 여러가지 이벤트 종류 (참고)
이벤트 등록할 때 'click' 이벤트 한가지만 써봤는데
아래 표와 같이 사용자의 동작에 따라 반응하는 다양한 이벤트들이 존재 한다.
마우스 이벤트
mousedown | 마우스 버튼을 누르는 순간 |
mouseup | 마우스 버튼을 눌렀다 떼는 순간 |
click | 왼쪽 버튼을 클릭한 순간 |
dblclick | 왼쪽 버튼을 빠르게 두 번 클릭한 순간 |
contextmenu | 오른쪽 버튼을 클릭한 순간 |
mousemove | 마우스를 움직이는 순간 |
mouseover | 마우스 포인터가 요소 위로 올라온 순간 |
mouseout | 마우스 포인터가 요소에서 벗어나는 순간 |
mouseenter | 마우스 포인터가 요소 위로 올라온 순간 (버블링이 일어나지 않음) |
mouseleave | 마우스 포인터가 요소에서 벗어나는 순간 (버블링이 일어나지 않음) |
키보드 이벤트
keydown | 키보드의 버튼을 누르는 순간 |
keypress | 키보드의 버튼을 누르는 순간 ('a', '5' 등 출력이 가능한 키에서만 동작하며, Shift, Esc 등의 키에는 반응하지 않음) |
keyup | 키보드의 버튼을 눌렀다 떼는 순간 |
포커스 이벤트
focusin | 요소에 포커스가 되는 순간 |
focusout | 요소로부터 포커스가 빠져나가는 순간 |
focus | 요소에 포커스가 되는 순간 (버블링이 일어나지 않음) |
blur | 요소로부터 포커스가 빠져나가는 순간 (버블링이 일어나지 않음) |
입력 이벤트
change | 입력된 값이 바뀌는 순간 |
input | 값이 입력되는 순간 |
select | 입력 양식의 하나가 선택되는 순간 |
submit | 폼을 전송하는 순간 |
스크롤 이벤트
scroll | 스크롤 바가 움직일 때 |
윈도우 창 이벤트
resize | 윈도우 사이즈를 움직일 때 발생 |
▶GitHub
'JS' 카테고리의 다른 글
(15) Interactive JavaScript (Event) - 이벤트 버블링 (0) | 2024.11.07 |
---|---|
(14) Interactive JavaScript (Event) - 이벤트 객체 (0) | 2024.11.06 |
(12) Interactive JavaScript - 비표준 속성 (0) | 2024.11.05 |
(11) Interactive JavaScript - Style (0) | 2024.10.16 |
(10) Interactive JavaScript - HTML 속성 다루기 (0) | 2024.10.15 |