Remove Event Listener method for a toggle

I have a simple click function, that when a button is clicked the user can’t scroll. This all works OK. The button works as toggle though, and on the ‘else’ part of the toggle, i.e. when the user clicks again, I want to remove the event listener that stop the user scrolling with the removeEventListener(); method. The function I am calling within this method isn’t working though?

I can’t seem to work out what the problem is?

codepen: https://codepen.io/emilychews/pen/MrBvzP

JS

var button = document.getElementById("button");

// function to be called and removed when button is clicked
function noscroll() {
    window.scrollTo(0, 0);
}

// TOGGLE EVENT LISTENER
var scrollToggle = false;

function toggleEventListener() {
    if (scrollToggle === false) {

        window.addEventListener("scroll", function(){
        noscroll();        
        }, false);

      scrollToggle = true;

    } else {

        window.removeEventListener("scroll", function(){
        noscroll();        
        }, false);

      scrollToggle = false;

    }
}

button.addEventListener("click", function() {
    toggleEventListener();
}, false)
body {margin: 0; padding: 0; height: 150vh;}

#button {font-family: arial;
  margin: 10px 0 0 30px;
  width: 100px;
  height: 50px;
  background: red;
  display: flex;
  justify-content: center;
  align-items: center;
  color: white;
  cursor: pointer;
}
<div id="button">Click Me</div>

Answer

I don’t believe you can remove an anonymous event handler. You need to name it so it knows which listener matches. We can reuse your noscroll function as our named handler.

Try running the snippet and you will see that it has your expected outcome.

https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/removeEventListener

var button = document.getElementById("button");

// function to be called and removed when button is clicked
function noscroll() {
    window.scrollTo(0, 0);
}

// TOGGLE EVENT LISTENER
var scrollToggle = false;

function toggleEventListener() {
    if (scrollToggle === false) {
        window.addEventListener("scroll", noscroll, false);
        scrollToggle = true;
    } else {
        window.removeEventListener("scroll", noscroll, false);
        scrollToggle = false;
    }
}

button.addEventListener("click", function () {
    toggleEventListener();
}, false)
body {margin: 0; padding: 0; height: 150vh;}

#button {font-family: arial;
  margin: 10px 0 0 30px;
  width: 100px;
  height: 50px;
  background: red;
  display: flex;
  justify-content: center;
  align-items: center;
  color: white;
  cursor: pointer;
}
<div id="button">Click Me</div>

We can simplify this further by moving our logic to check scrollToggle into the handler itself. Removing the need to add/remove the handler. (And it can stay anonymous.)

var button = document.getElementById("button");

// TOGGLE EVENT LISTENER
var scrollToggle = false;

window.addEventListener("scroll", () => { 
  if (scrollToggle) {
    window.scrollTo(0, 0) 
  }
}, false);

function toggleEventListener() {
  scrollToggle = !scrollToggle;
}

button.addEventListener("click", function () {
  toggleEventListener();
}, false)
body {margin: 0; padding: 0; height: 150vh;}

#button {font-family: arial;
  margin: 10px 0 0 30px;
  width: 100px;
  height: 50px;
  background: red;
  display: flex;
  justify-content: center;
  align-items: center;
  color: white;
  cursor: pointer;
}
<div id="button">Click Me</div>

Leave a Reply

Your email address will not be published. Required fields are marked *