1

I am currently doing a simple rock, paper, scissors game with javascript however, removeEventListener() doesn't seem to be working in my code. I know I used a loop to apply the event listeners to the buttons, so I will figure out the loop to remove them later.

For now, I don't understand why my code won't remove the event listener on the button that's clicked:

let btns = document.querySelectorAll('button');

btns.forEach(function(item) {

    item.addEventListener('click', function(event) {
        results.textContent = '';
        playRound(event.target.className, getComputerChoice());
        
        if (playerCount == 5) {
            item.removeEventListener('click', event);
            winner.textContent = `YOU WON 5 GAMES!`;

        }else if (cpuCount == 5) {
            item.removeEventListener('click', event);
            winner.textContent = `YOU LOSE! CPU WINS 5`;
        }
    });
});
2
  • @Mina's answer answers your question. However, I wonder what is the purpose of of removing the listener in the first place. If you don't want the user to continue playing after 5 wins/loses you can simply have an IF statement in the click handler that doesn't allow anything to happen if 5 wins/loses happened. Commented Sep 20, 2022 at 19:47
  • @imvain2 True, however, this is more of trying to understand adding and removing event listeners. Commented Sep 20, 2022 at 19:53

2 Answers 2

3

The second parameter removeEventListener took is the addEventListner callback function, so I suggest you to separate the addEventListner callback to a named function and use it in both addEventListner and removeEventListner

let btns = document.querySelectorAll('button');

function onClickHandler(event) {
        results.textContent = '';
        playRound(event.target.className, getComputerChoice());
        
        if (playerCount == 5) {
            item.removeEventListener('click', onClickHandler);
            winner.textContent = `YOU WON 5 GAMES!`;

        }else if (cpuCount == 5) {
            item.removeEventListener('click', onClickHandler);
            winner.textContent = `YOU LOSE! CPU WINS 5`;
        }
    });
}

btns.forEach(function(item) {

    item.addEventListener('click', onClickHandler);
}
Sign up to request clarification or add additional context in comments.

Comments

0

The safest or best answer to this would probably be the one posted by Mina, however I am posting this answer as another valid alternative for those who are looking into similar issues.

While you can declare an actual callback function that can be easily added and removed to/from an event listener, you can also pull in an anonymous callback function by passing in ...args to your callback function as well. Once ...args is passed in and exists, you can use args.callee as the callback function for removeEventListener() to remove the current anonymous function from an element.

I should also note that ...args specifically applies to arrow functions. A more classic function(event) { setup like the one posted by OP can use an arguments variable that exists for those types of functions. Arrow functions require you to also pass in ...args to obtain additional argument values.

let btns = document.querySelectorAll('button');

btns.forEach(item => {
  item.addEventListener('click', (e, ...args) => {
    results.textContent = '';
    playRound(e.target.className, getComputerChoice());
    
    if(playerCount == 5) {
      item.removeEventListener('click', args.callee);
      winner.textContent = `YOU WON 5 GAMES!`;
    } else if(cpuCount == 5) {
      item.removeEventListener('click', args.callee);
      winner.textContent = `YOU LOSE! CPU WINS 5`;
    }
  });
});

1 Comment

Yes! I knew I've seen this before, except it was: ```item.removeEventListener('click', arguments.callee);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.