탱구탱구 개발자 일기

이벤트

 

우리가 이용하는 웹사이트에는 수많은 기능을 제공한다. 특정 메뉴 버튼을 클릭할 때 정보가 노출된다던가 반대로 정보를 입력하면 서버에 저장 기능 등 말이다. 이러한 기능들이 없다면 웹페이지는 그냥 글자만 있는 전자문서와 동일하다. 주로 우리들은 이 웹페이지에 있는 기능을 이용하기 위해서 마우스나 키보드를 조작하여 기능을 실행한다. 바로 이러한 행위들을 이벤트라고 부른다.

 

이벤트 처리기

 

이벤트 처리기란 말그대로 이벤트 청취자, 즉 위와 같은 이벤트가 발생하는 것을 감지하는 역할을 한다. 따라서 이벤트가 발생했을 때 이벤트를 받은 다음 처리기 안에 있는 코드를 실행한다. 대개 특정 기능을 하는 함수가 실행 대상이다. 이벤트 처리기는 이벤트 핸들러이벤트 리스너가 있다.

 

  • 핸들러 : 하나의 요소하나의 이벤트 처리 가능. HTML 태그에 설정하거나, DOM 요소 객체의 이벤트 처리기 프로퍼티 설정하는 방법이다.
  • 리스너 : 하나의 요소복수의 이벤트 처리 가능. addEventListner 메서드

 

주요 이벤트 처리기

이벤트 처리기 이름 이벤트 종류
onclick, dblclick 마우스로 (더블)클릭했을 때
onmousedown, up 마우스 버튼을 눌렀을 때, 떼었을 때
onmousemove, onmouseout, onmouseover 마우스 포인터가 HTML 요소 위에서 움직일 때
마우스 포인터가 HTML 요소 위에서 벗어날 때
마우스 포인터가 HTML 요소 위에 놓여있을 때
onkeydown, onkeypress, onkeyup 키보드의 키를 눌렀을 때
키를 누르고 손가락을 떼었을 때
키에서 손가락을 떼었을 때
onchange, onblur, onfocus input 요소의 값이 바뀌었을 때
input 요소가 포커스를 잃었을 때
input 요소에 포커스를 맞추었을 때
onselect, onsubmit 텍스트 필드 등의 텍스트를 선택했을 때
폼 제출 버튼을 눌렀을 때
onload, onunloadWeb HTML을 모두 읽어 들였을 때
웹 페이지가 메모리에서 내려갈 때(ex. 다른 페이지로 전환)
onabort, onerror 페이지나 이미지 읽어 들이기가 중단되었을 때
페이지나 이미지를 읽어 들이는 동안 오류가 발생했을 때
onresize HTML 요소의 크기가 바뀌었을 때

 

이벤트 처리기 등록

 

- 이벤트 핸들러

 

  • HTML 태그에 설정

이 방법은 사실상 간단한 방법이지만 HTML와 자바스크립트 코드가 섞여있기 때문에 나중에 유지보수가 힘들다. 또한 태그 하나에 하나의 이벤트 처리만 등록할 수 있기 때문에, 만약 HTML 문서 하나에 여러 개의 자바스크립트 파일이 import 되고 동일한 이벤트 핸들러명을 가진 코드가 있다면 제대로 동작하지 않을 수 있다. 기본적으로 HTML과 자바스크립트는 분리하는게 맞다.

<button onclick="showSideNav();">

 

  • DOM 요소 객체의 이벤트 처리기 프로퍼티에 설정

이 방법을 사용하면 HTML과 자바스크립트를 분리할 수 있지만 위와 마찬가지로 특정 DOM 요소 객체에 하나의 이벤트 핸들러만 등록시키는 단점이 있다.

let sideNav = document.getElementById("sideNav");
let btn = document.getElementById("btn");
btn.onclick = showSideNav();

function showSideNav() {
    sideNav.style.display = "block";
}

   

- 이벤트 리스너

 

  • addEventListener 메서드 사용
// addEventListner 메서드 사용
target.addEventListener(type, listner, useCapture);

// 예시
let btn2 = document.getElementById("btn2");
btn2.addEventListener(type, listner, useCapture);

addEventListner로 등록한 함수는 이벤트 리스너라고 부른다. 이것을 사용하면 위 코드에서 btn2라는 요소에 여러 개의 이벤트 리스너를 등록시킬 수 있다.

 

  • 구성 요소
    • target : 이벤트 리스너를 등록한 DOM 요소( or 객체, 노드)
    • type : 이벤트 유형을 뜻하는 문자열. 기존 이벤트 처리기 이름에서 on을 생략할 것(ex. click, mousemove.. )
    • listner : 이벤트가 발생했을 때 처리를 담당하는 콜백 함수의 참조
    • useCapture : 이벤트 단계
      • true : 캡처링 단계
      • false : 버블링 단계(default)

 

  • 이벤트 리스너 예시
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<script>
    window.onload = function () {
        let btn3 = document.getElementById("btn3");
        let btn5 = document.getElementById("btn5");
        
        // 버튼 위에 마우스 포인터 올렸을 때 버튼 색상이 blue, 벗어나면 red
        btn3.addEventListener("mouseover", function (e) {
            e.currentTarget.style.backgroundColor = "blue";
            btn3.addEventListener("mouseout", function (e) {
                e.currentTarget.style.backgroundColor = "red";
            }, false);
        }, false);
        
        // 버튼 클릭시 알람창 활성화
        btn5.addEventListener("click", showInfo, false);
    };
    function showInfo() {
        alert("클릭이벤트");
    }
</script>
<body>
    <button id="btn3">버튼3</button>
    <button id="btn5">버튼5</button>
</body>
</html>

 

반대로 removeEventListner 메서드를 사용하면 등록된 이벤트 리스너를 삭제할 수 있다.

  • btn5에 연결된 이벤트처럼 리스너가 기명 함수일 때는 삭제하고 싶은 해당 함수 이름을 넘김
  • btn3에 연결된 이벤트처럼 리스너가 익명 함수일 때는 이벤트 리스너 안에서 호출해서 arguments.callee를 넘겨서 스스로 삭제시켜야 함
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<script>
    // 버튼 위에 마우스 포인터 올렸을 때 버튼 색상이 blue, 벗어나면 red
    window.onload = function () {
        let btn3 = document.getElementById("btn3");
        let btn5 = document.getElementById("btn5");

        btn3.addEventListener("mouseover", function (e) {
            e.currentTarget.style.backgroundColor = "blue";
            btn3.addEventListener("mouseout", function (e) {
                e.currentTarget.style.backgroundColor = "red";
            }, false);
            // red에서 blue로 색이 변경된 후 기존 이벤트 리스너 삭제
            // 리스너가 익명 함수일 때는 removeEventListner에 arguments.callee를 넘김
            btn3.removeEventListener("mouseover", arguments.callee, false);
        }, false);

        btn5.addEventListener("click", showInfo, false);
        btn5.addEventListener("click", showInfo2, false);
        
        // showInfo2 이벤트 삭제
        btn5.removeEventListener("click", showInfo2, false);

    };
    function showInfo() {
        console.log("클릭이벤트 로그");
    }
    function showInfo2() {
        alert("클릭이벤트 알람창");
    }
</script>
<body>
    <button id="btn3">버튼</button>
    <button id="btn5">버튼5</button>
</body>
</html>

 

  • 장점
    • 같은 요소의 같은 이벤트에 이벤트 리스너를 여러개 등록 가능
    • 버블링, 캡처링 단계 모두에서 활용 가능
    • removeEventListner, stopPropagation, preventDefault를 활용하여 이벤트 전파 제어 가능
    • HTML 태그를 포함한 모든 DOM 노드에 이벤트 리스너 등록 가능

다음 포스팅에선 좀 더 구체적으로 들어가서 이벤트 객체 및 이벤트 전파에 대해 알아보도록 하겠다.

 

이 글을 공유합시다

facebook twitter kakaoTalk kakaostory naver band
loading