0

I am building a game and on a certain condition I need to remove the event listener from a <div> that has just been clicked. I don't want the user to click twice on the same div. I'm trying to use .removeEventListener

Here's my code.

let Divs = document.querySelectorAll(".data")

Divs.forEach((v, k) => {
  v.addEventListener("click", (e) => {
    clic(e, v, k)
  });
});

function clic(e, v, k) {
  console.log("CLICK");
  Divs[k].removeEventListener("click", (e) => {
    clic(e, v, k)
  });
}
Michael M.
  • 10,486
  • 9
  • 18
  • 34
Gio
  • 1
  • 1
    if you search here, you'll find a lot of answer on remove event listener. Basically, your add event listener has to call a function, the remove remove it. Search there are nice description how to do that – pier farrugia Feb 04 '23 at 09:38
  • it works with a simple syntax but if you want things more complicated it doesn't work anymore... the previous answers didn't help – Gio Feb 04 '23 at 10:08
  • you need to pass the same function reference. – pilchard Feb 04 '23 at 10:50
  • Does this answer your question? [removeEventListener on anonymous functions in JavaScript](https://stackoverflow.com/questions/4950115/removeeventlistener-on-anonymous-functions-in-javascript) – pilchard Feb 04 '23 at 10:53
  • also: [remove event listeners with extra arguments](https://stackoverflow.com/questions/69242724/remove-event-listeners-with-extra-arguments/69243303#69243303) and [Remove Event Listeners that need to Receive Multiple Arguments JS](https://stackoverflow.com/questions/74354162/remove-event-listeners-that-need-to-receive-multiple-arguments-js/74354356#74354356) – pilchard Feb 04 '23 at 10:55
  • if you look at my code it is the same function – Gio Feb 04 '23 at 12:11

2 Answers2

0

a game with 9 div! Are you making a tictactoe?:)

little snippet with 9 div, I've added a button in div 6 to remove event for div5

I put the remove in a function, so you can call it with a condition somewhere in your code. You have to pass the name of the div

Array.from(document.querySelectorAll('.grid>div')).forEach(el => {
  el.addEventListener('click', divclickadd);
});

function divclickadd(ev) {
  console.log(ev.target);
}

document.querySelector('button').addEventListener('click', function(evt) {
  evt.stopImmediatePropagation();
  console.log(evt.target.className);
  divclickremove(evt.target.className);
});

function divclickremove(div) {
  const el = document.querySelector('#' + div);
  console.log(el);
  el.removeEventListener('click', divclickadd);
}
*,
*:before,
*:after {
  box-sizing: border-box;
}

html,
body {
  overflow: hidden;
  margin: 0;
  padding: 0;
}

body {
  width: 100vw;
  height: 100vh;
}

.grid {
  display: grid;
  grid-template-rows: repeat(3, 1fr);
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
  width: 100%;
  height: 100%;
}

.grid>div {
  display: flex;
  justify-content: center;
  align-items: center;
}
<div class="grid">
  <div id="div1" style="background-color: red">div 1</div>
  <div id="div2" style="background-color: blue">div 2</div>
  <div id="div3" style="background-color: green">div 3</div>
  <div id="div4" style="background-color: yellow">div 4</div>
  <div id="div5" style="background-color: purple">div 5</div>
  <div id="div6" style="background-color: brown">div 6
    <button class="div5">remove event 5</button>
  </div>
  <div id="div7" style="background-color: darkolivegreen">div 7</div>
  <div id="div8" style="background-color: orangered">div 8</div>
  <div id="div9" style="background-color: cadetblue">div 9</div>
</div>
pier farrugia
  • 1,520
  • 2
  • 2
  • 9
  • thank you! this is really nice. but I am not sure it applies to what I needed to do. You have to remove the event listener to the button that has been clicked at a certain condition! not just any button with a certain ID. it is a Memory game I am building... https://www.gqgrafica.it/mem.html it's bugged for more than one reason. first reason is if you click the same letter over and over you will eventually win the game. – Gio Feb 04 '23 at 12:19
0

as I said, I put a button to remove event as example to call the function. You can call the function to remove other way. As the function is written at the moment, you just need to pass the name of the id. Regarding what you are saying it you need to remove event listener of a specific clicked button...

let condition = false;

Array.from(document.querySelectorAll('button.game')).forEach(el => {
  el.addEventListener('click', divclickadd);
});

function divclickadd(ev) {
  ev.stopImmediatePropagation();
  console.log(ev.target);
  if (condition) {
    divclickremove(ev.target);
  }
}

document.querySelector('button.condition').addEventListener('click', function(evt) {
  evt.stopImmediatePropagation();
  condition = true;
  console.log(condition);
});

function divclickremove(el) {
  console.log(el);
  el.removeEventListener('click', divclickadd);
}
button {
  display: block;
}
<button class="game">button event</button>
<button class="game">button event</button>
<button class="game">button event</button>
<button class="game">button event</button>
<button class="game">button event</button>
<button class="game">button event</button>
<button class="game">button event</button>
<button class="game">button event</button>
<button class="game">button event</button>
<br>
<button class="condition">change condition value</button>

if you click on change condition value, next time you click on button event, it'll fire because remove not yet fired. Next next time, it's not remove event has been done.

pier farrugia
  • 1,520
  • 2
  • 2
  • 9