인터랙티브 웹 개발의 기초인 브라우저 이벤트 에 대해 정리해보자.
이벤트 객체 e
이벤트 객체는 이벤트가 발생했을 때 이벤트를 발생시킨 요소와 발생한 이벤트에 대한 정보가 담겨있다. 이벤트 객체는 이벤트 핸들러의 첫 번째 인자로 받는다. 위치는 첫 번째로 항상 고정이다.
e.currentTarget - 핸들러를 할당받은 요소 (this와 같음)
e.target - 실제 이벤트가 발생한 node
e.type - 브라우저 이벤트 종류
e.key - key값을 문자열로 나타냄
e.keyCode - key값을 코드로 나타냄 ( *deprecated 라고 하니 이 방법은 지양하도록 하자)
e.defaultPrevented - preventDefault 호출여부
e.preventDefault() - 기본으로 실행되는 이벤트를 취소함
예를 들어, form태그 안에 있는 input에서 submit하게 되면 기본적으로 페이지를 reload하게 된다. 새로고침을 원하지 않는다면 아래와 같이 e.preventDefault() 메서드를 호출해서 이벤트를 막을 수있다.
$input.addEventListener('keydown', (e) => {
if (e.key === 'Enter') {
e.preventDefault();
onSubmit();
}
});
이벤트 종류
키보드 & 마우스 이벤트
keydown - 문자, 숫자, 방향, 특수문자, ctrl, opt, shift, tab, delete, enter 를 눌렀을 때 연속 발생. (그 외 1번 발생)
keypress - 문자, 숫자, 방향, 특수문자, ctrl, opt, shift, tab, delete, enter 를 눌렀을 때 연속 발생. (그 외 0번 발생) ( *deprecated 라고 하니 이 방법은 지양하도록 하자)
keyup - 키보드 버튼을 땠을 때 1번 발생
mousedown/mouseup - 마우스 왼쪽 버튼을 눌렀을 때/땠을 때
click - 마우스 왼쪽 버튼을 눌렀을 때
scroll - 스크롤을 움직일 때
userInput.addEventListener("keyup", e => {
if (e.keyCode === 13) {
onSearch(e.target.value);
}
});
window.addEventListener('scroll', () => {
console.log(window.scrollTop);
console.log(window.pageYOffset);
});
값변경 이벤트
input - input(text, checkbox, radio), select, textarea 요소의 값이 입력되었을 때
change - input(text, checkbox, radio), select, textarea 요소의 값이 변경되고 포커스를 잃었을 때
문서 이벤트
DOMContentLoaded - DOM 생성이 완료되었을 때
load - 문서의 모든 리소스가 로드되었을 때 (더 오래 걸림)
DOM이 로드되기 전에 함수가 실행되는 것을 방지해준다. 단 script를 body 맨 아래 위치시키면 사용하지 않아도 된다.
window.addEventListner('DOMContentLoaded', () => {
const darkmodeToggle = document.querySelector('.darkmodeToggle');
const clickDarkmodeToggleHandler = () => {
darkmodeToggle.classList.toggle('dark');
}
darkmodeToggle.addEventListener('click', clickDarkmodeToggleHandler);
}
이벤트 위임
새로운 데이터를 로드해서 HTML을 추가된다면 각 요소에 이벤트 리스너를 새로 설정해주어야 한다. 이벤트 위임은 부모 이벤트에 이벤트 리스너를 위임해서 다는 방식으로 이 작업을 간결화 해준다. 데이터 수십개 수백개가 동적으로 로드되는 상황에서도 이벤트리스너를 단 한 번만 할당해주면 되고 성능개선에도 도움이 된다고 한다.
const postGroup = document.querySelector('.post');
const clickHandler = (e) => {
let element = e.target;
while (!element.classList.contains('like-button')) {
element = element.parentNode;
if (element.nodeName === 'BODY') {
return ;
}
}
if (element.classList.contains('like-button')) {
incrementLike(element);
}
}
postGroup.addEventListener('click', clickHandler);
target을 원하는 요소로 제한하기 위해 while문 안의 내용이 추가된다. 하위 요소에 또 다른 이벤트 핸들러를 할당해야 할 일이 없다면 CSS로 더 쉽게 제어할 수 있다.
.like-button-img {
pointer-events: none;
}
참고자료
'HTML ⁄ CSS ⁄ JS' 카테고리의 다른 글
Javascript - 'this' 키워드로 객체에 접근하기 (0) | 2021.02.14 |
---|---|
JavaScript - 유용한 내장 메서드(find, filter, every, some, reduce, repeat) (0) | 2021.02.10 |
JavaScript - 호출 스케줄링(setTimeout, setInterval, requestAnimationFrame) (0) | 2021.02.10 |
CSS - vw & vh 단위, em & rem 단위 (0) | 2021.02.02 |
CSS - Transform, Transition, Animation, 3D (0) | 2021.01.20 |