removeEventListener

Can someone help me implement removeEventListener? I have multiple event listeners and I want to to make it so when one is clicked the others are removed, however my current removeEventListener is not working… Please see code below.

playerDiscard() {
 

    //if player card x is clicked run the click event

    playerCardSlot1.addEventListener('click', () => this.clickHandler(), {once:true});
    playerCardSlot2.addEventListener('click', () => this.clickHandler2(), {once:true});
    playerCardSlot3.addEventListener('click', () => this.clickHandler3(), {once:true});
    playerCardSlot4.addEventListener('click', () => this.clickHandler4(), {once:true});
    playerCardSlot5.addEventListener('click', () => this.clickHandler5(), {once:true});



  }

now if one clickEvent is ran how do I remove the other 4?

clickHandler() {
    playerCardSlot1.innerHTML = '';
    upcard.classList.add('disabled')
    upcard.style.display = 'none';
    this.count = 1;
    console.log('count is '+this.count);


    var newDiv = document.createElement('div');
    newDiv.innerText = upcard.firstElementChild.dataset.value.slice(2).trim();
    newDiv.classList.add('card', upcard.firstElementChild.className.split(' ')[1]);
    newDiv.dataset.value = upcard.firstElementChild.dataset.value;
    playerCardSlot1.appendChild(newDiv);

    playerCardSlot2.removeEventListener('click', () => this.clickHandler2(), {once:true});
    playerCardSlot3.removeEventListener('click', () => this.clickHandler3(), {once:true});
    playerCardSlot4.removeEventListener('click', () => this.clickHandler4(), {once:true});
    playerCardSlot5.removeEventListener('click', () => this.clickHandler5(), {once:true});



    
    playerCardSlot1.classList.add('disabled')
    playerCardSlot2.classList.add('disabled')
    playerCardSlot3.classList.add('disabled')
    playerCardSlot4.classList.add('disabled')
    playerCardSlot5.classList.add('disabled')


    this.stopAnimation();
    return this.playHand();
}

You should use named functions, not anonymous functions. Or you can use the once option if it should only run once (no IE support).

<button>1</button>
<button>2</button>
<button>3</button>
const buttons = document.querySelectorAll("button");

buttons.forEach((btn) => {
  btn.addEventListener(
    "click",
    ({ target }) => {
      console.log(`Clicked: ${target.textContent}`);
    },
    { once: true }
  );
});

I am using once option, but that is not my issue. I am not sure if you looked at my code, but I just need to remove other event listeners once one has been clicked. However, my trouble is that if I do something like playerCardSlot1.addEventListener('click', this.clickHandler, {once:true}); i get an HTMLDivError saying this.stopAnimation and this.playHand are not functions in the scope. Not really sure how to tackle this…

We have to see more of the code to know the context. Post a link to a GitHub or a live version on something like Codepen.

Looking at the method names and some of the other code it just doesn’t look like you are doing this correctly. It’s highly unlikely that you actually want multiple clickHandler methods on separate elements. More likely you want one method with some logic inside it and targeting the click target (and/or doing DOM traversal). Inside the single handleClick method you then can remove all the other event listeners after the logic by just looping the collection of elements.

Example code
<button>1</button>
<button>2</button>
<button>3</button>
const buttons = document.querySelectorAll("button");

buttons.forEach((btn) => {
  btn.addEventListener("click", handleClick, { once: true });
});

function handleClick({ target }) {
  // do some logic
  target.style.color = "red";
  console.log(`Clicked: ${target.textContent}`);

  buttons.forEach((btn) => {
    btn.removeEventListener("click", handleClick, { once: true });
  });
}
1 Like

I was able to solve the problem doing this:

  this.slots = [playerCardSlot1, playerCardSlot2, playerCardSlot3, playerCardSlot4, playerCardSlot5];
  this.handlers = this.slots.map(slot => () => this.clickHandler(slot));

and then for the method:

clickHandler(slot) {
    slot.innerHTML = '';
    upcard.style.display = 'none';
    upcard.classList.add('disabled')

    let newDiv = document.createElement('div');
    newDiv.innerText = upcard.firstElementChild.dataset.value.slice(2).trim();
    newDiv.classList.add('card', upcard.firstElementChild.className.split(' ')[1]);
    newDiv.dataset.value = upcard.firstElementChild.dataset.value;
    slot.appendChild(newDiv);
    this.slots.forEach(slot => slot.classList.add('disabled'));
    this.slots.forEach((slot, position) => slot.removeEventListener('click', this.handlers[position]));
    this.stopAnimation();
    return this.playHand();
  }

lastly the adding of the actual click:

playerDiscard() {
  this.slots.forEach((slot, position) => slot.addEventListener('click', this.handlers[position], {once:true}));
}

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.