removeEventListener?

김윤진·2022년 3월 11일
0

JavaScript

목록 보기
1/10

reference
https://kostasbariotis.com/removeeventlistener-and-this/

이벤트 리스너 등록을 위해 addEventListener 메소드를 사용한다
등록된 이벤트 리스너를 제거하기 위해 removeEventListener 메소드를 사용한다

target.addEventListener(type, listener, useCapture);

target.removeEventListener(type, listener, useCapture);

호출되는 listener 함수의 this는 target이 되는 엘리먼트(.)를 가르킨다

bind, call, apply 메소드는 근본적으로 동일한 목적인
this에 대한 참조를 제어할 때 사용한다

bind() 는 this 값을 설정하고 새로운 함수를 생성한다

call(), apply() 는 함수를 생성하는 것이 아니라 호출한다


const createButton = (() => {
	function addEvents() {
    	this.el.addEventListener("click", this.clickHandler);
    }
    
    return class Button {
    	constructor() {
        	this.el = document.createElement("button");
        }
        
        clickHandler() {
        	console.log("clickHandler");
        }
    }
})();

const newButton = new createButton();
newButton.el.dispatchEvent(new Event("click"))

클릭 이벤트에 대한 핸들러 함수를 등록하기 위한 addEvnets 함수는 Button 클래스가 아닌 다른 context에 동작한다


const createButton = (() => {
	function addEvents() {
    	this.el.addEventListener("click", this.clickHandler);
    }
    
    return class Button {
    	constructor() {
        	this.el = document.createElement("button");
            
        	addEvents();
        }
        
        clickHandler() {
        	console.log("clickHandler");
        }
    }
})();

const newButton = new createButton();
newButton.el.dispatchEvent(new Event("click"))

addEvents 함수는 현재 window를 참조하고 있기 때문에 동작하지 않는다


addEvents 함수에서의 this.el은 button이 되어야 한다
call 메서드를 사용해서 this 값을 전달해야 한다

const createButton = (() => {
	function addEvents() {
    	this.el.addEventListener("click", this.clickHandler);
    }
    
    return class Button {
    	constructor() {
        	this.el = document.createElement("button");
            
        	addEvents.call(this);
        }
        
        clickHandler() {
        	console.log("clickHandler");
        }
    }
})();

const newButton = new createButton();
newButton.el.dispatchEvent(new Event("click"))

정상적으로 동작한다


clickHanlder에서 arr에 1을 추가하는 로직을 추가하도 실행하면

const createButton = (() => {
  function addEvents() {
    console.log(this); // Button {el: button, arr: Array(0)}
    this.el.addEventListener('click', this.clickHandler);
  }

  return class Button {
    constructor() {
      this.el = document.createElement('button');
      this.arr = [];

      addEvents.call(this);
    }

    clickHandler() {
      console.log(this); // button
      this.arr.push(1);
    }
  };
})();

const newButton = new createButton();
newButton.el.dispatchEvent(new Event('click'));

clickHandler 메서드 내의 this는 button element이다

addEvents 함수에 call을 통해 원하는 this를 전달한 것처럼
clickHandler 함수 또한 this를 전달해주면 된다
bind를 통해 this를 전달 및 새로운 함수르 생성함으로 콜백 형식을 유지할 수 있다


const createButton = (() => {
  function addEvents() {
    console.log(this); // Button {el: button, arr: Array(0)}
    
    this.el.addEventListener('click', this.clickHandler.bind(this));


  }

  return class Button {
    constructor() {
      this.el = document.createElement('button');
      this.arr = [];

      addEvents.call(this);
    }

    clickHandler() {
      console.log(this); // Button {el: button, arr: Array(0)}
      this.arr.push(1);
      console.log(this.arr); // [1]
    }
  };
})();

const newButton = new createButton();
newButton.el.dispatchEvent(new Event('click'));

removeEventListener 를 사용해 이벤트 리스너를 작성해보자

const createButton = (() => {
  function addEvents() {
    console.log(this); // Button {el: button, arr: Array(0)}
    this.el.addEventListener('click', this.clickHandler.bind(this));
  }
  
  function removeEvents() {
    console.log(this)
    this.el.removeEventListener('click', this.clickHandler.bind(this));
  }

  return class Button {
    constructor() {
      this.el = document.createElement('button');
      this.arr = [];

      addEvents.call(this);
    }

    clickHandler() {
      console.log(this); // Button {el: button, arr: Array(0)}
      this.arr.push(1);
      console.log(this.arr); // [1]
    }
    
    removeHandler() {
      removeEvents.call(this);
    }
    
  };
})();

const newButton = new createButton();
newButton.el.dispatchEvent(new Event('click')); // [1]
newButton.removeHanlder();
newButton.el.dispatchEvent(new Event('click')); // [1, 1]

bind 를 통해 리스너 함수를 지정했다
bind 는 새로운 함수를 생성하기 때문에 addEventListener와 removeEventListener의 리스너 함수는 같지 않다


bind 한 함수를 리스너에서 할당하는 것이 아니라 미리 할당해놓으면 가능하다
click event가 발생하더라도 clickHandler 메서드가 호출되지 않는다

const createButton = (() => {
  function addEvents() {
    console.log(this); // Button {el: button, arr: Array(0)}
    this.el.addEventListener('click', this.clickHandler);
  }
  
  function removeEvents() {
    console.log(this)
    this.el.removeEventListener('click', this.clickHandler);
  }

  return class Button {
    constructor() {
      this.el = document.createElement('button');
      this.arr = [];

	  this.clickHandler = this.clickHandler.bind(this);
      addEvents.call(this);
    }

    clickHandler() {
      console.log(this); // Button {el: button, arr: Array(0)}
      this.arr.push(1);
      console.log(this.arr); // [1]
    }
    
    removeHandler() {
      removeEvents.call(this);
    }
    
  };
})();

const newButton = new createButton();
newButton.el.dispatchEvent(new Event('click')); // [1]
newButton.removeHanlder();
newButton.el.dispatchEvent(new Event('click')); // [1]

0개의 댓글