티스토리 뷰

버튼 클릭 이벤트에서 이벤트 핸들러를 등록하는 두가지 방법은 한 가지는 dom 요소에 접근한 다음 onClick 프로퍼티를 활용하는 방법이고 다른 한 가지는 HTML 속성을 활용하는 방법입니다.

HTML 태그에서 직접 이벤트를 다루는 일은 일반적으로 잘 사용되지도 않고 몇 가지 문제가 있습니다.

// 이벤트 핸들러 등록하기
let btn = document.querySelector('#myBtn');

btn.onclick = function () {
  console.log('Hi Codeit');
}
btn.onclick = function () {
  console.log('Hi again');
}

일단 각 버튼을 눌러보면 콘솔 탭에 등록한 이벤트 핸들러가 잘 동작하는 것을 확인할 수 있습니다.

그런데 사실 onclick 프로퍼티를 활용하는 방법도 한 가지 문제를 가지고 있습니다.

innerHTML이나 className같은 프로퍼티를 활용할 때도 프로퍼티에 어떤 값을 할당하는 방식은 기존에 있던 값을 덮어쓰는 형태로 동작하기 때문에 기존에 있는 값을 유지하면서 일부만 수정하기는 어려운 단점이 있습니다.

onclick 프로퍼티도 새로운 이벤트 핸들러를 할당하게 되면 기존의 값을 덮어쓰기 때문에 저장하고 실행해보면 Hi Codeit은 사라지고 Hi again만 출력되는 모습을 확인할 수 있습니다. 

실제로 중요한 이벤트를 덮어쓰는 실수를 할 수도 있고 또 여러 개의 이벤트 핸들러를 다룰 수도 없다는 단점이 있습니다.

 

이러한 문제를 해결하기 위해서 하나의 이벤트 핸들러 안에 다시 여러 개의 이벤트 핸들러를 넣는 방법이 있지만 이마저도 중간에 새로운 이벤트를 추가하거나 혹은 이 중 하나를 제거해야 하는 상황은 대처하기 어려운 문제도 있고 지금은 간단한 이벤트지만 각 이벤트 별로 중요한 리턴 값이 있을 경우에는 그 리턴 값도 다뤄야 하는 훨씬 더 복잡한 문제가 생기게 됩니다. 

// 이벤트 핸들러 등록하기
let btn = document.querySelector('#myBtn');

function event1(){
  console.log('Hi Codeit');
}

function event2(){
  console.log('Hi again');
}
btn.onclick = function () {
  event1();
  event2();
}

그래서 onclick 프로퍼티를 활용하지 않고 이벤트 핸들러를 등록하는 한가지 방법이 있습니다.

바로 addEventListener 라는 메소드를 활용하는 겁니다.

사실 이 방법이 이벤트 핸들러를 등록할 때 가장 권장되는 방법입니다.

이벤트 핸들러를 등록하고 싶은 요소에 addEventListener를 호출하는데 첫 번째 파라미터로 이벤트 타입을 문자열로 전달하고 두 번째 파라미터로 이벤트 핸들러를 전달하면 됩니다.

그래서 이렇게 메소드를 여러 번 호출하게 되면 하나의 요소에 여러 개의 독립적인 이벤트 핸들러를 등록할 수가 있습니다.

저장하고 실행해보면 event1과 event2가 잘 동작하는 것을 확인할 수 있습니다.

// 이벤트 핸들러 등록하기
let btn = document.querySelector('#myBtn');

function event1() {
  console.log('Hi Codeit');
}

function event2() {
  console.log('Hi again');
}

// elem.addEventListener(event, handler)
btn.addEventListener('click', event1);
btn.addEventListener('click', event2);

// elem.removeEventListener(event, hendler)
btn.removeEventListener('click', event2);

그리고 이렇게 등록한 이벤트는 removeEventListener를 통해서 이벤트 핸들러를 개별적으로 제거할 수도 있습니다.

등록할 때와 다 똑같이 먼저 event 타입을 문자열로 전달하고 등록할 때 전달했던 이벤트 핸들러를 두 번째 파라미터로 전달하게 되면 해당 이벤트가 삭제되는 방식입니다.

코드를 저장하고 실행해서 버튼을 클릭해 보면 event2는 등록되었다가 다시 삭제되었기 때문에 event1만 동작하는 모습을 확인할 수 있습니다. 그런데 여기서 한 가지 꼭 기억해야 될 점은 이벤트를 삭제할 때 반드시 등록할 때 사용했던 핸들러를 그대로 전달해야 된다는 점입니다.

 

이벤트를 등록할 때 핸들러를 전달하는 부분에서 함수를 바로 작성할 수도 있기 때문에 등록할 때와 똑같은 모양의 함수를 삭제할 때도 써주면 뭔가 정상적으로 삭제될 것처럼 오해할 수도 있는데요.

모양은 똑같지만 서로 다른 함수이기 때문에 이 이벤트 핸들러가 정상적으로 삭제되지 않습니다.

코드를 저장하고 실행해보면 이벤트 핸들러가 계속해서 동작하는 것을 확인할 수 있습니다.

그래서 만약 이벤트 핸들러를 삭제해야 될 필요가 있다면 반드시 이벤트를 등록할 때 외부에 함수를 만들어서 해당 함수의 이름으로 핸들러를 전달해 줘야 된다는 점을 꼭 기억해두면 좋을 것 같습니다.

// 이벤트 핸들러 등록하기
let btn = document.querySelector('#myBtn');

function event1() {
  console.log('Hi Codeit');
}

function event2() {
  console.log('Hi again');
}

// elem.addEventListener(event, handler)
btn.addEventListener('click', event1);
btn.addEventListener('click', event2);

// elem.removeEventListener(event, hendler)
btn.removeEventListener('click', event2);

btn.addEventListener('click', function(){
 console.log('event3');
})
btn.removeEventListener('click', function(){
 console.log('event3');
})

그리고 여기서 또 한 가지 주의해야 될 점은 이벤트 핸들러 부분에는 함수 이름만 전달해 주면 된다는 점입니다.

간혹 소괄호를 붙여주는 실수를 하는 경우가 있습니다. 그런데 이렇게 하면 이부분을 해석할 때 함수를 그대로 호출해버려서 함수를 호출한 리턴값 그러니까 이 경우에는 리턴 값이 없기 때문에 undefined가 두 번째 파라미터로 전달돼 버려서 사실상 이벤트 핸들러가 등록되지 않게 됩니다. 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함