[JavaScript] Click 이벤트 중복 해결하기

Lpla

·

2021. 12. 14. 21:35

반응형

제이쿼리 resize 이벤트로 700px 이하에서만 클릭 이벤트를 적용하고 700px을 초과하면

어떠한 이벤트도 없는 버튼을 만들고자 한다.

 

HTML

<button class="btn">button</button>
<div class="width"></div>

button은 클릭 이벤트를 생성할 요소, width 클래스는 윈도우 가로 크기를 볼 수 있도록 표시할 요소이다.

 

 

JS

let ww = $(window).width();

checkResize();

$(window).on('resize', function() {
  ww = $(window).width();
  $('.width').text(ww);
  checkResize();
});

function checkResize() {
  if (ww <= 700) {
    $(".btn").on('click', function() {
      $('body').append('<div>클릭</div>');
    });
  }
}

 

자바스크립트를 간단하게 살펴보면, 변수 ww에 윈도우 가로 크기를 할당하고,

화면의 크기가 변하면 ww를 다시 할당한다.

그렇게 실시간으로 확인할 수 있는 ww를 width 클래스에 텍스트로 표시하고 checkResize 함수를 실행한다.

checkResize 함수는 700px 이하일 때, button에 클릭 이벤트를 실행하는데 그 이벤트는 "클릭"이라는 요소를 DOM에 추가하는 것이다.

 

 

See the Pen 잘못된 클릭 이벤트 by lpla (@lpla) on CodePen.

 

 

하지만 막상 코드를 실행하면 원하는 대로 동작하지 않는다.

 

 

먼저 클릭이 한 번만 실행되는 것이 아니라 중첩되어 여러번 실행된다.

그리고 700px을 초과하더라도 이벤트는 여전히 삭제되지 않고 존재한다.

 

문제의 핵심은 화면을 리사이즈할 때마다 클릭 이벤트가 계속해서 생성되는 데 있다.

쉽게 말하자면 699px 에서도 클릭 이벤트가 생성되고 698px 에서도 클릭 이벤트가 생성된다.

그리고 이 이벤트는 서로 다른 이벤트로 취급한다.

 

위 코드에서 조건문은 클릭 이벤트를 감싸고 있다. 이것은 이벤트가 생성되는 조건이지 실행되는 조건이 아니다.

실행되는 조건을 만드려면 이벤트 내부에 조건문을 만들어야 한다.

바로 아래처럼 수정해야 한다.

 

function checkResize() {
  $(".btn").on('click', function() {
    if (ww <= 700) {
      $('body').append('<div>클릭</div>');
    }
  });
}

 

 

오직 한 번만 클릭 이벤트를 동작하게 하려면 그 이전의 클릭 이벤트를 모두 제거해야 한다.

바로 .off() 메서드를 사용하면 된다.

클릭 이벤트를 생성할 때 .on('click') 을 사용하는 것처럼 .off('click') 을 사용하여 이벤트를 삭제할 수 있다.

 

 

JS

let ww = $(window).width();

checkResize();

$(window).on('resize', function() {
  ww = $(window).width();
  $('.width').text(ww);
  checkResize();
});

function checkResize() {
  $('.btn').off('click').on('click', function() {
    if (ww <= 700) {
      $('body').append('<div>클릭</div>');
    }
  });
}

 

 

See the Pen 제대로 된 클릭 이벤트 by lpla (@lpla) on CodePen.

 

 

 

 

순수 자바스크립트

이 과정을 순수 자바스크립트로 작업하려면 제이쿼리와는 다른 문제가 발생한다.

제이쿼리의 .off() 메서드와 달리 .removeEventListener()는 익명함수에 사용할 수 없다.

해결할 수 있는 방법이야 물론 있겠지만 그렇게 되면 코드가 길어지게 되니 차라리 다른 방법을 쓰는 것이 낫다.

바로 요소를 복제하여 새로운 요소를 만들어 내고 기존 요소는 지우는 것이다.

아래 코드는 스택오버플로의 인기 답변을 참고하여 작성했다.

See the Pen 제대로 된 클릭 이벤트 (vanilla) by lpla (@lpla) on CodePen.

 

 

 

반응형