Search code examples
javascriptmodel-view-controllerpublish-subscribe

Javascript's removeEventListener not working


I have tried some solutions already such as that callback functions are both the same. I still can't get it to work.

removeClickEventHandler function inside view module is not working. Event listener is applied from controller. I abstracted some code from the view module but I left controller module as it is.

Controller code:

import navigationView from "./view/navView.js";
import ticTacToeView from "./view/ticTacToeView.js";
import ticTacModule from "./modules/ticTacModule.js";

class Controller {
      constructor() {
        navigationView.addHoverEventHandlers(navigationView.hoverFunction);
        navigationView.addClickHandler(this.showContent.bind(this));
      }
    
      showContent() {
        ticTacToeView.renderContent(navigationView.clickedContent);
        ticTacToeView.addClickEventHandler(this.ticTacToeControl.bind(this));
        ticTacToeView.addHoverHandler(ticTacToeView.hoverFunction);
      }
    
      ticTacToeControl(clickedBox) {
        if (ticTacToeView.checkIfBoxEmpty(clickedBox)) {
          ticTacToeView.createMark(clickedBox, ticTacModule.activePlayer);
          ticTacModule.updateBoardState(clickedBox);
          ticTacModule.changeActivePlayer();
          ticTacToeView.highlightActivePlayer(ticTacModule.activePlayer);
          ticTacModule.checkForWinner();
          if (ticTacModule.winner) {
            ticTacToeView.renderWinner(ticTacModule.winner);
            ticTacToeView.removeClickEventHandler(this.ticTacToeControl);
          }
        }
      }
    }

This is view module code:

import View from "./View.js";

class TicTacToeView extends View {

  addClickEventHandler(fn) {
    const ticTacContainer = document.querySelector(".tic-tac-toe");
    ticTacContainer.addEventListener("click", fn, true);
  }

  removeClickEventHandler(fn) {
    const ticTacContainer = document.querySelector(".tic-tac-toe");
    ticTacContainer.removeEventListener("click", fn, true);
  }
}
export default new TicTacToeView();

Solution

  • bind creates a new function with a new reference. this.ticTacToeControl and this.ticTacToeControl.bind(this) are two different functions with two different references. Store the function reference in a variable and use it to remove the event listener.

    class Controller {
      constructor() {
        navigationView.addHoverEventHandlers(navigationView.hoverFunction);
        navigationView.addClickHandler(this.showContent.bind(this));
      }
    
      showContent() {
        ticTacToeView.renderContent(navigationView.clickedContent);
        this.handler = this.ticTacToeControl.bind(this);
        ticTacToeView.addClickEventHandler(this.handler);
        ticTacToeView.addHoverHandler(ticTacToeView.hoverFunction);
      }
    
      ticTacToeControl(clickedBox) {
        if (ticTacToeView.checkIfBoxEmpty(clickedBox)) {
          ticTacToeView.createMark(clickedBox, ticTacModule.activePlayer);
          ticTacModule.updateBoardState(clickedBox);
          ticTacModule.changeActivePlayer();
          ticTacToeView.highlightActivePlayer(ticTacModule.activePlayer);
          ticTacModule.checkForWinner();
          if (ticTacModule.winner) {
            ticTacToeView.renderWinner(ticTacModule.winner);
            ticTacToeView.removeClickEventHandler(this.handler);
          }
        }
      }
    }