자바스크립트

[자바스크립트] 이벤트와 DOM 조작 2편

취업 드가자잇 2024. 8. 1. 17:34

 

 

이전글에서 DOM을 조작할 수 있도록 해주는 DOM 셀럭터에 대해 알아보았다면, 이번 글에서는 DOM 셀럭터로 선택된 요소에 이벤트를 달아주는 방법에 대해 알아볼까 한다.

이벤트란 클릭, 스크롤부터 시작해서 마우스관련 이벤트 등 우리가 웹사이트를 이용하며 일상적으로 사용하는 그러한 기능들을 말한다.

이 글에서는 event를 추가하는 법, 제거하는 법, 그리고 사용시 유의점에 대해 간략하게 다뤄보고자 한다.

 

addEventListener()

이 메서드는 특정 요소에 이벤트를 등록할 수 있게 해주는 메소드이다. 

element.addEventListener(event, function, useCapture);

 

첫번째 인자값으로 이벤트명(ex. onClick, input, change 등) 을 받고, 두번째 인자값으로는 해당 이벤트가 발생할 때 실행할 함수를 받는다. 그리고 마지막 useCapture는 선택사항인데, 이벤트 전파 방식을 결정해주는 녀석이다. 

useCapture는 Boolean 타입이며, true를 지정하면 캡쳐링을, false라면 버블링을 사용한다는 뜻이다. 

기본값은 false이며, 따라서 기본적으로 이벤트는 버블링 단계에서 발생한다.

(이벤트 캡처링, 버블링에 대한 자세한 설명은 자바스크립트 -> 이벤트 캡쳐 & 이벤트 버블에 있다). 

 

removeEventListener() 

이 메서드는 이름에서 느껴지듯이 특정 요소에서 이벤트 핸들러를 제거하는 메소드이다.

element.removeEventListener(event, function, useCapture);

 

일단 addEventListener와 받는 인자값은 같다.

이 메서드의 중요하다고 생각하는 점은 removeEventListener()로 제거하려는 이벤트 핸들러는 addEventListener()를 통해 사용해 추가한 것과 같은 함수여야 한다는 것이다. 

다른 말로 이는 익명 함수로 이벤트 핸들러를 추가했을 경우, 그 함수를 removeEventListener()로 제거할 수 없음을 의미한다. 

const button = document.getElementById('myButton');

    // 이벤트 리스너 추가 (익명 함수 사용)
    button.addEventListener('click', () => {
      console.log('Button clicked!');
    });

    // 이벤트 리스너 제거 (동일한 익명 함수 참조를 사용할 수 없음)
    button.removeEventListener('click', () => {
      console.log('Button clicked!');
    });

    // 삭제이후에도 여전히 클릭 시 "Button clicked!" 출력됨

 

즉, 이벤트 리스너를 등록할 때 사용한 함수 참조와 동일한 함수 참조를 사용해야 이벤트 리스너를 제거할 수 있다.

이를 위해 함수가 동일한 메모리 영역을 가리켜야 합니다.

 

이벤트 리스너 사용 시 주의사항

개인적으로 이벤트 리스너 사용 시 주의해야할 점이 몇가지 있다고 생각하는데, 그 중에 하나가 브라우저는 일부 이벤트에 대해 기본 동작을 가지고 있다는 것이다. 예를 들어, input이든 button이든 type=submit이 붙이면 제출하는 순간 페이지가 새로고침되고, 클릭 이벤트가 a태그에 발생하면 브라우저는 해당 링크로 이동하는 것들이 예시이다. 

이러한 기본 동작을 막고, 원하는 동작대로 움직이게 하기 위해서는 event.preventDefault()를 이용해 기본동작을 방지할 수 있다. 

 

두번째는 this인데, 이벤트 핸들러를 일반 함수(function 키워드 포함)으로 정의하면 this는 이벤트가 발생한 요소를 참조한다.

하지만 이벤트 핸들러를 익명 함수, 화살표 함수로 정의하면 this 키워드는 부모의 this를 참조하므로 이 점을 유의해야 할 것이다. 

const button = document.getElementById('myButton');

    button.addEventListener('click', function() {
      console.log(this); // 일반 함수의 경우, 이벤트가 발생한 버튼 요소를 가리킴
    });

 

const button = document.getElementById('myButton');

    const obj = {
      name: 'Object',
      logThis: function() {
        console.log(this); // obj를 가리킴
        button.addEventListener('click', () => {
          console.log(this); // 화살표 함수는 부모 컨텍스트의 this (즉, obj)를 가리킴
        });
      }
    };

    obj.logThis();