DOM 이벤트 기초
자바스크립트는 이벤트를 처리하는 다양한 경로를 제공합니다.
대표적으로 HTML 페이지 태그에 인라인으로 태그에 이벤트를 등록할 수 있습니다.
또는, 자바스크립트 코드로 직접 이벤트를 등록할 수도 있습니다.
인라인으로 HTML 태그에 이벤트를 등록하는 방법은 어떤 이벤트가 등록되었고, 어떤 함수가 실행되는지 바로 알 수 있는 장점이 있는 반면, HTML 태그와 스크립트 코드가 분리되지 않아 코드 유지보수와 관리가 불편합니다.
반복되는 다량의 이벤트를 등록하는 경우 수많은 반복 작업을 해야 합니다.
반면, 자바스크립트에 전문적인 지식이 없어도 자바스크립트 코드를 핸들링 할 수 있는 장점이 있습니다.
웹디자이너 레벨에서도 슬라이드 배너에 사용하는 마우스 클릭 같은 이벤트는 인터넷에서 적당히 맞는 자바스크립트 함수를 복사해 붙여넣고 HTML 태그에 onclick="함수명" 정도 붙여 넣어주면 무리없이 동작시킬 수 있습니다.
이벤트 등록과 관리를 자바스크립트 코드 기반으로 사용하는 방식은 작성 코드량이 더 많고 다소 작성이 어렵습니다.
모든 이벤트 제어가 자바스크립트 코드로 이루어지며, HTML 태그에는 이벤트와 관련된 코드가 전혀 없습니다.
자바스크립트 코딩 방향이 HTML 과 자바스크립트 코드가 완전히 분리되는 추세이므로 을 꼭 기본으로 사용해야 합니다.
HTML 코드에 이벤트 처리 코드가 들어있는 것은 아마추어 처럼 보이며, 팀 단위 협업을 하는데도 많은 불편함을 줍니다.
여기서는 인라인 방식으로 이벤트를 등록하는 것은 별도로 다루지 않습니다.
최근의 개발 추세가 인라인으로 자바스크립트 이벤트 처리를 하지 않는 것을 기본으로 하고 있기 때문에, 자바스크립트 코드로 이벤트의 생애주기를 모두 관리하는 코딩 방법 만을 설명합니다.
이벤트 등록
모든 자바스크립트 이벤트 처리는 addEventListener() 함수에서 시작합니다.
자바스크립트로 이벤트 처리를 하려고 경우 addEventListener() 함수로 HTML 엘리먼트 노드에 이벤트를 등록합니다.
addEventListener() 함수 구조는 다음과 같습니다.
const ref = document.addEventListener('이벤트타입', function(e){
//이벤트 콜백 처리
});
이벤트타입: 사용자가 발생시킨 웹페이지 안에서의 액션입니다. 마우스를 클릭했으면 "click", 키보드를 눌렀으면 "keydown" 과 같이 이벤트 종류 키워드를 사용합니다.
콜백 함수: 이벤트가 발생하면 실행하는 함수입니다. 파라메터로 이벤트 객체를 전달하며, 이벤트 객체에 이벤트를 발생시킨 HTML 요소와, 다양한 이벤트 정보가 들어 있습니다. 콜백함수는 익명함수로 작성할 수도 있지만, 이벤트 삭제할 때 함수명을 필요로 하므로 가능하면 별도의 함수로 작성하고, 함수명을 인자로 넣는 것을 추천합니다.
예를 들어
let btn = document.querySelector('#btnsave');
btn.addEventLIstener('click', function(e){
console.log(e.target.value+' clicked!');
});
또는
funciton callbackFunc(e){
console.log(e.target.value+' clicked!');
}
btn.addEventLIstener('click', callbackFunc);
이렇게 버튼 엘리먼트에 클릭이 발생하면 콜백 함수가 실행되도록 할 수 있습니다.
등록 옵션 추가
addEventListener() 함수는 파라메터로 옵션을 추가할 수 있습니다.
인터넷 익스플로러에서는 지원되지 않습니다. 웹브라우저 호환성이 필요한 경우 옵션 설정은 사용하지 말아야 합니다.
capture: 기본값 false. 이벤트를 캡쳐링(Capturing) 방식으로 전파(Propagation) 할지를 결정합니다. 이벤트 캡쳐링과 버블링에 대한 이해가 필요하므로 이벤트 캡쳐링과 버블링에 대한 글을 먼저 봐야 합니다.
capture 옵션은 옵션 객체 대신, 단독 옵션 파라메터로 불리언(true/false) 값을 전달할 수 있습니다.
예를 들어
btn.addEventLIstener('이벤트종류', 콜백함수, true);
이런 방식으로 단독 옵션 사용 가능합니다.
once: 이벤트가 한번만 호출되고 등록한 이벤트 리스너가 삭제됩니다. 한번 사용후 폐기해야 하는 경우 추가의 이벤트 삭제 처리를 하지 않아도 됩니다.
passive: 기본값 false. true 인 경우 콜백 함수에서 preventDefault()(이벤트 취소 및 타겟의 기본 동작 차단) 를 사용할 수 없습니다. 이벤트에 의해 스크롤이 블럭되는 것을 막아주며, 주로 모바일 브라우저의 스크롤 성능 향상을 위해 추가된 옵션입니다.
옵션을 적용해 이벤트 리스너를 등록하는 방법은 다음과 같습니다.
btn.addEventLIstener('이벤트 종류', 콜백함수, 이벤트 옵션 객체);
예를 들어
const options = {capture: false, once: true, passive: true}; // 옵션 객체 생성
//콜백 함수clickFunc = function (e){ console.log(e.target.value+' clicked!');}
btn.addEventLIstener('click', clickFunc, options); // 이벤트 리스너 등록
이렇게 옵션 객체를 사용할 수 있습니다.
등록 가능한 이벤트들
자바스크립트에서 등록할 수 있는 이벤트 종류는 수 백 가지 입니다.
그중 웹페이지 제어에 주로 사용하는 이벤트들을 알아 보겠습니다.
이벤트명 | 타입 | 대상 |
발생 시점 |
DOMContentLoaded | 이벤트 | DOM |
DOM 트리가 완성된 직후.(렌더링 전) HTML만 로딩 완료된 상태 |
load | UI이벤트 | 도큐먼트, 엘리먼트 |
리스소와 그 외 리소스 의존 리소스가 모두 로딩 완료되었을 때 |
reset | 이벤트 | 폼 |
폼 리셋 버튼 클릭 |
submit | 이벤트 | 폼 |
폼 전송 버튼 클릭, 또는 전송 이벤트 발생 |
resize | UI이벤트 | 도큐먼트뷰 |
브라우저 크기 변경 |
scroll | UI이벤트 | 도큐먼트뷰, 엘리먼트 | 브라우저 화면 스크롤, 또는 엘리먼트 요소 내부 스크롤 |
focus | 포커스이벤트 | 엘리먼트 | 엘리먼트가 포커스를 받았을 때(이벤트 버블링 없음) |
blur | 포커스이벤트 | 엘리먼트 | 엘리먼트가 포커스를 잃었을 때(이벤트 버블링 없음) |
keydown | 키보드이벤트 | 입력요소 |
키보드 키 누름 |
keypress | 키보드이벤트 | 입력요소 | 키보드 키 누름 상태 지속(반복 발생함). Fn, CapsLock 은 제외 |
keyup | 키보드이벤트 | 입력요소 | 키보드 키 누름 해제 |
mouseenter | 마우스이벤트 | 엘리먼트 | 엘리먼트 안으로 마우스 커서가 들어옴(들어올 때 1번 발생) |
moserover | 마우스이벤트 | 엘리먼트 | 엘리먼트 위에 마우스 커서가 위치함 |
mousemove | 마우스이벤트 | 엘리먼트 | 마우스 커서가 이동 |
mousedown | 마우스이벤트 | 엘리먼트 | 마우스 버튼 누름 |
mouseup | 마우스이벤트 | 엘리먼트 | 마우스 버튼 누름 해제 |
click | 마우스이벤트 | 엘리먼트 | 마우스 버튼 클릭 |
contextmenu | 마우스이벤트 | 엘리먼트 | 컨텍스트 메뉴 표시(오른쪽 마우스 버튼 클릭 |
!주의할 점
제이쿼리 라이브러리를 이용해 HTML 로딩 완료된 시점을 체크하는 방법은 $(document).ready(function(){}) 입니다.
이것은 자바스크립트의 document.adddEventListener('DOMContentLoaded', function(){}) 과 같습니다.
"DOMContentLoaded" 이벤트 대신 "load" 이벤트를 사용하면 포함된 리소스까지 모두 로딩이 완료된 후 이벤트가 호출됩니다. 이것은 제이쿼리 라이브러리의 $(document).onload(function(){}) 과 같습니다.
이벤트 삭제
이벤트를 삭제하려면 등록한 이벤트 타입과 콜백함수 이름을 알아야 합니다.
이벤트를 등록할 때 capture 옵션을 사용한 경우에는 이벤트 삭제할 때 반드시 같은 옵션값을 명시해야 합니다.
자바스크립트 이벤트 리스너 등록 함수는 capture 옵션을 사용한 경우, 다른 capture 옵션 값으로 같은 이벤트와 콜백함수를 중복 등록할 수 있습니다.
등록한 이벤트 리스너를 삭제할 때도 각각 구분해 옵션을 적용해 삭제해야 합니다.
document.removeEventListener(이벤트타입, 등록된 콜백함수, 옵션객체 );
와 같이 사용해야 하며
예를 들어
function callbackFunc(e){ console.log(e.target.value+' clicked!');}document.addEventListener('click', callbackFunc, {capture: true}); // 추가document.removeEventListener('click', callbackFunc, {capture: true}); // 삭제
이렇게 삭제할 수 있습니다.
위에 등록한 이벤트 리스너는
document.removeEventListener('click', callbackFunc, {capture: false});
document.removeEventListener('click', callbackFunc, false);
와 같은 이벤트 삭제 함수로는 등록한 이벤트를 삭제할 수 없습니다.
옵션값을 적용한 경우 반드시 옵션값까지 명시를 해야 합니다.
이벤트 삭제 함수는 별도 반환값이 없기 때문에 삭제 성공 여부를 알 수 없습니다.
이벤트 리스너 등록시 등록한 콜백 함수 명과 옵션 값을 주의해야 합니다.
특별히 옵션이 필요없는 이벤트 등록시에는 이벤트 옵션을 생략하고 사용하는 방식이 등록한 이벤트를 삭제할 때 더 유연하게 대응할 수 있습니다.