[이벤트] - 이벤트 핸들러 등록과 제거

Donggu(oo)·2022년 11월 12일
0

JavaScript

목록 보기
39/49
post-thumbnail

1. 이벤트 핸들러 등록


  • 이벤트 핸들러(event handler)란 이벤트가 발생했을 때 브라우저에 호출을 위임한 함수다. 즉, 이벤트가 발생하면 브라우저에 의해 호출될 함수가 이벤트 핸들러다.

1) HTML 속성(이벤트 핸들러 어트리뷰트) 방식

  • HTML 요소의 속성 중에는 이벤트에 대응하는 이벤트 핸들러 속성이 있다. 이벤트 속성의 이름은 onclick과 같이 on 접두사와 이벤트의 종류를 나타내는 이벤트 타입으로 이루어져 있다.

  • 이벤트 핸들러 속성 값으로 함수 호출문 등의 문(statement)을 할당하면 이벤트 핸들러가 등록된다.

  • 여러개의 핸들러 할당이 불가능하다.

  • HTML 속성을 이용한 이벤트 핸들러 할당은 자주 쓰이지 않는다. HTML 태그 중간에 자바스크립트가 들어가 있으면 어색하기 때문이다. 긴 코드를 끼워 넣는 게 불가능한 점도 이유 중 하나이다.

  • 주의할 점은 이벤트 핸들러 속성 값으로 함수 참조가 아닌 함수 호출문을 할당하는 것이다.

함수 참조 VS 함수 호출

  • 함수 참조 : func
  • 함수 호출 : func()
// input 태그의 onclick 속성에 click 핸들러를 할당
<input value="클릭해 주세요." onclick="alert('클릭!')" type="button">
  
// HTML 속성값으로 긴 코드가 들어가야 한다면, 함수를 만들어서 호출하는 방법을 사용한다.
// 아래 버튼을 클릭하면 countRabbits 함수가 호출된다.
<input type="button" onclick="countRabbits()" value="토끼를 세봅시다!">  

<script>
  function countRabbits() {
    for(let i=1; i<=3; i++) {
      alert(`토끼 ${i}마리`);
    }
  }
</script>
  • 위 예제와 같이 함수 호출문을 할당하게 될 경우, 이때 이벤트 핸들러 속성 값은 사실 암묵적으로 생성될 이벤트 핸들러의 함수 몸체를 의미한다.

  • 이벤트 핸들러 속성 값은 파싱되어 아래와 같은 함수를 암묵적으로 생성하고, 이벤트 핸들러 속성 이름과 통일한 onclick 이벤트 핸들러 프로퍼티에 할당한다.

function onclick(event) {
  countRabbits();
}

2) DOM 프로퍼티(이벤트 핸들러 프로퍼티) 방식

  • DOM 프로퍼티의 키는 HTML 속성 방식과 마찬가지로 onclick과 같이 on 접두사와 이벤트의 종류를 나타내는 이벤트 타입으로 이루어져 있다.

  • 이벤트 핸들러 프로퍼티에 함수를 바인딩(메서드와 객체를 묶어놓는 것)하면 핸들러가 등록된다.

  • 여러개의 핸들러 할당이 불가능하다.

  • HTML 속성 방식도 결국 DOM 노드 객체의 이벤트 핸들러 프로퍼티로 변환되므로 DOM 프로퍼티 방식과 동일하다고 할 수 있다.

  • 이벤트 핸들러를 등록하기 위해서는 이벤트를 발생시킬 객체인 이벤트 타겟(event target)과 이벤트의 종류를 나타내는 문자열인 이벤트 타입(event type) 그리고 이벤트 핸들러를 지정해야 한다.

<input type="button" id="button" value="클릭해 주세요.">
  
<script>
  button.onclick = function() {
    alert('클릭!');
  };
</script>

  • DOM 프로퍼티 방식으로 등록한 이벤트 핸들러를 제거하려면 onclick = null 같이 null을 할당한다.
// 아래와 같이 핸들러를 하나 더 추가하면, 기존 핸들러는 덮어 씌워진다.
// HTML 속성에 할당한 alert('이전') 창은 뜨지 않고 스크립트의 alert('이후') 창만 뜬다.
<input type="button" id="elem" onclick="alert('이전')" value="클릭해 주세요.">
  
<script>
  elem.onclick = function() { // 기존에 작성된 핸들러를 덮어씀
    alert('이후'); // 이 alert창만 보인다.
  };
</script>

3) addEventListner 메서드 방식

  • HTML 속성과 DOM 프로퍼티를 이용한 이벤트 핸들러 할당 방식은 하나의 이벤트에 여러개의 핸들러를 할당할 수 없다. 이러한 문제를 해결하기 위해 여러 개의 핸들러를 할당할 때는 addEventListner라는 메서드를 사용한다.
  • 기본 문법
EventTarget.addEventListener(eventType, eventHandler, [options]);
  • 매개변수
    • eventType : 이벤트 이름(ex : "click"), (on 접두사를 붙이지 않는다)
    • eventHandler : 이벤트 핸들러 함수명
    • options : 아래 프로퍼티를 갖는 객체
      • once : true 이면 이벤트가 트리거 될 때 리스너가 자동으로 삭제된다.
      • capture : 어느 단계에서 이벤트를 다뤄야 하는지를 알려주는 프로퍼티로, 버블링과 캡쳐링이 있다. 호환성 유지를 위해 options를 객체가 아닌 true/false로 할당하는 것도 가능한데, 이는 {capture: true/false}와 동일하다.
    • passive: true이면 리스너에서 지정한 함수가preventDefault()를 호출하지 않는다.
  • addEventListner를 여러 번 호출하면 아래와 같이 핸들러를 여러 개 붙일 수 있다.
<input id="elem" type="button" value="클릭해 주세요.">

<script>
  function handler1() {
    alert('첫 번째 출력!');
  };

  function handler2() {
    alert('두 번째 출력!');
  }

  elem.addEventListener("click", handler1); // '첫 번째 출력!' alert창 출력
  elem.addEventListener("click", handler2); // `두 번째 출력!` alert창 출력 
</script>

2. 이벤트 핸들러 제거


1) removeEventListner

  • addEventListner 메서드로 등록한 이벤트를 제거하려면 removeEventListner 메서드를 사용한다.

  • removeEventListner 메서드에 전달할 인수는 addEventListner 메서드와 동일하지만, addEventListner 메서드에 전달한 인수와 removeEventListner 메서드에 전달한 인수가 동일하지 않으면 이벤트 핸들러가 제거되지 않는다.

// 아래와 같이 이벤트를 할당하고 삭제해도 핸들러는 지워지지 않는다.
elem.addEventListener('click', function() {
  alert('감사합니다!');
}
elem.removeEventListener('click', function() {
  alert('감사합니다!');
}                    

// 위 예제를 아래와 같이 함수를 변수에 할당해서 수정하면 정상적으로 핸들러가 삭제된다.
let handler = function() {
  alert( '감사합니다!' );
}

input.addEventListener("click", handler);
input.removeEventListener("click", handler);  // 이벤트 핸들러가 제거 된다.
  • 아래 예제는 'Hello' 버튼을 클릭하면 'Hello World!'라는 alert창을 띄우는 버튼을 만들고, 클릭하면 'Hello' 버튼 이벤트가 삭제되는 'Bye' 버튼을 만드는 예제이다.
<input type="button" id="btn1" value="Hello">
<input type="button" id="btn2" value="Bye">

<script>
// Hello 버튼 이벤트
  let helloBtn = document.querySelector("#btn1");

  let clickListener = function() {
    alert('Hello World!');
  };

  helloBtn.addEventListener('click', clickListener);

// Bye 버튼 이벤트
  let byeBtn = document.querySelector("#btn2");

  byeBtn.addEventListener('click', function() {
  	helloBtn.removeEventListener('click', clickListener);
  });
</script>

0개의 댓글