Проблемы с функциями внутри функции в javascript (слушатель событий) - PullRequest
0 голосов
/ 28 мая 2020

Получил эти прослушиватели событий из функций. Работает нормально, кроме случаев, когда 2 звука подряд совпадают, второй звук иногда не произносится. Не знаю, откуда это взялось. Другая проблема: если игра перезагружается, когда она не закончена, я получаю двойные звуки. Я не знаю, где удалить EventListeners, если они являются проблемой. Разве не сложно иметь одно и то же событие (щелкнуть по ячейкам) с двумя разными целями?

Вот код:

//Pour placer les images dans le tableau (sinon enlever cette partie pour avoir les images en ligne avec fonction shuffle dans un flex)

let cards = document.getElementsByClassName('card');
let nbreCards = cards.length;
cell1.appendChild(card1);
cell2.appendChild(card2);
cell3.appendChild(card3);
cell4.appendChild(card4);
cell5.appendChild(card5);
cell6.appendChild(card6);

//Pour mélanger les images dans le tableau.
function shuffle() {
  let cardVar = [card1, card2, card3, card4, card5, card6];

  for (let cardPosition = cardVar.length - 1; cardPosition >= 1; cardPosition--) {
    let numrandom = Math.floor(Math.random() * (cardPosition + 1));
    let sauve = cardVar[cardPosition];
    cardVar[cardPosition] = cardVar[numrandom];
    cardVar[numrandom] = sauve;
  }
  //Mélange aléatoire des cartes du tableau
  cell1.appendChild(cardVar[0]);
  cell2.appendChild(cardVar[1]);
  cell3.appendChild(cardVar[2]);
  cell4.appendChild(cardVar[3]);
  cell5.appendChild(cardVar[4]);
  cell6.appendChild(cardVar[5]);
}


//Pour jouerSon aléatoire  sans doublon ... à finir...

//Récupérer array des sons et nombre de sons :



function sonsAleatoires() {
  //Arrays of win and loose            
  let reussitesArray = [];
  let echecsArray = [];



  let sounds = document.getElementsByTagName('audio');
  let nbreSounds = sounds.length;
  let soundsArray = [];

  for (let i = 0; i < nbreSounds; i++) {
    sons = sounds[i];
    let x = sons.getAttributeNode('id').value;
    soundsArray.push(x);
  }

  //Duplique deux fois la liste des sons pour en avoir une vingtaine
  let soundsArray2 = soundsArray.slice();
  let soundsArray3 = soundsArray2.slice();
  let soundsArray4 = soundsArray.concat(soundsArray2, soundsArray3);


  //Randomize sounds 
  for (let soundPosition = soundsArray4.length - 1; soundPosition >= 1; soundPosition--) {
    let numrandom = Math.floor(Math.random() * (soundPosition + 1));
    let sauve = soundsArray4[soundPosition];
    soundsArray4[soundPosition] = soundsArray4[numrandom];
    soundsArray4[numrandom] = sauve;
  }

  console.log(soundsArray4);

  let p = -1;
  let numsnd;

  son();

  function son() {
    p++;
    if (p >= soundsArray4.length) {
      return;
    } else {
      let sonAjouer = document.getElementById(soundsArray4[p]);
      let snd = sonAjouer.getAttributeNode('id').value;
      numsnd = Number(snd.charAt(3));
      sonAjouer.play();
    } //fin du if             
  } //fin de son

  let cells = document.getElementsByTagName('td');
  let nbreCells = cells.length;
  for (var y = 0; y < nbreCells; y++) {
    cells[y].addEventListener('click', donnerResultat);
  }

  function donnerResultat() {
    let idCell = "";
    let contenuCell = "";
    let numImage = 0;
    idCell = (this.id);
    contenuCell = document.getElementById(idCell).lastElementChild.getAttributeNode('id').value;
    numImage = Number(contenuCell.charAt(4));
    if (p >= soundsArray4.length) {
      return;
    }

    //Compares id soundn and id img cliqued  
    if (numsnd === numImage) {
      reussitesArray.push(1);


      document.getElementById(idCell).style.backgroundColor = "#83f500";
      setTimeout(function() {
        document.getElementById(idCell).style.backgroundColor = "";
      }, 1000);


    } else {
      echecsArray.push(contenuCell);
      document.getElementById(idCell).style.backgroundColor = "#f13022";
      setTimeout(function() {
        document.getElementById(idCell).style.backgroundColor = ""
      }, 1000);
    } //fin du if 

  } //end of function donnerResultat

  //next sound 
  for (var c = 0; c < nbreCells; c++) {
    cells[c].addEventListener('click', son, false);
  }

} //end of sonsAleatoires
*,
*:before,
*:after {
  margin: 0px;
  box-sizing: border-box;
}

html,
body {
  height: 100%;
  width: 100%;
}

body {
  justify-content: center;
  align-items: center;
  background-color: #ffeb3b63
}

h1 {
  font-size: 5vw;
  color: #FF5722;
}

.main {
  background-color: orange;
  width: 100%;
  position: relative;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
}

.card {
  position: relative;
  margin: auto;
}

.card img {
  max-height: 12vw;
  width: auto;
  position: relative;
  border-radius: 1em;
  margin: auto;
  border: 1px solid #9C27B0;
  cursor: pointer;
}

.buttons {
  width: 15%;
  position: absolute;
  top: 10vw;
}

.buttons ul {
  list-style: none;
}

#button1 {
  display: none;
}

#button,
#button1,
#button3,
#button4 {
  position: relative;
  max-height: 10vw;
  float: right;
}

table {
  margin: auto;
  width: 65%;
}

table,
td {
  border: 1px solid #9c27b0;
  //border-collapse: collapse;
  padding: 2px;
  text-align: center;
  font: 4vw bold;
  color: #FFC107;
  background-color: #d0e21b6e
}

td {
  width: 31%;
}

.cell {
  cursor: pointer;
  background-color: #795548a1
}

p {
  position: relative;
  color: blue;
  font-size: 4vw;
  left: 50px;
}
image

Ответы [ 2 ]

0 голосов
/ 29 мая 2020

Слушатель событий добавляется к ячейкам при каждом вызове sonsAleatoires().

function sonsAleatoires() {

  /* ... */

  function son() {
    /* code snip */        
  } //fin de son

  /* ... */

  // add click listener to each cell:

  //next sound 
  for (var c = 0; c < nbreCells; c++) {
    cells[c].addEventListener('click', son, false);
  }

}

Это приведет к появлению нескольких слушателей для каждой ячейки. Чтобы предотвратить использование нескольких слушателей, убедитесь, что слушатели 'son' добавляются только один раз.

Введите переменную sonListenersAdded:

let cards = document.getElementsByClassName('card');
let nbreCards = cards.length;
cell1.appendChild(card1);
cell2.appendChild(card2);
cell3.appendChild(card3);
cell4.appendChild(card4);
cell5.appendChild(card5);
cell6.appendChild(card6);

// add this here:
let sonListenersAdded = false;

Затем замените это:

for (var c = 0; c < nbreCells; c++) {
  cells[c].addEventListener('click', son, false);
}

с таким:

if (!sonListenersAdded) {
  for (let cell of cells) {
    cell.addEventListener('click', son, false);
  }
  sonListenersAdded = true;
}

Рабочий код:

//Pour placer les images dans le tableau (sinon enlever cette partie pour avoir les images en ligne avec fonction shuffle dans un flex)

let cards = document.getElementsByClassName('card');
let nbreCards = cards.length;
cell1.appendChild(card1);
cell2.appendChild(card2);
cell3.appendChild(card3);
cell4.appendChild(card4);
cell5.appendChild(card5);
cell6.appendChild(card6);
let sonListenersAdded = false;

//Pour mélanger les images dans le tableau.
function shuffle() {
  let cardVar = [card1, card2, card3, card4, card5, card6];

  for (let cardPosition = cardVar.length - 1; cardPosition >= 1; cardPosition--) {
    let numrandom = Math.floor(Math.random() * (cardPosition + 1));
    let sauve = cardVar[cardPosition];
    cardVar[cardPosition] = cardVar[numrandom];
    cardVar[numrandom] = sauve;
  }
  //Mélange aléatoire des cartes du tableau
  cell1.appendChild(cardVar[0]);
  cell2.appendChild(cardVar[1]);
  cell3.appendChild(cardVar[2]);
  cell4.appendChild(cardVar[3]);
  cell5.appendChild(cardVar[4]);
  cell6.appendChild(cardVar[5]);
}


//Pour jouerSon aléatoire  sans doublon ... à finir...

//Récupérer array des sons et nombre de sons :



function sonsAleatoires() {
  //Arrays of win and loose
  let reussitesArray = [];
  let echecsArray = [];



  let sounds = document.getElementsByTagName('audio');
  let nbreSounds = sounds.length;
  let soundsArray = [];

  for (let i = 0; i < nbreSounds; i++) {
    sons = sounds[i];
    let x = sons.getAttributeNode('id').value;
    soundsArray.push(x);
  }

  //Duplique deux fois la liste des sons pour en avoir une vingtaine
  let soundsArray2 = soundsArray.slice();
  let soundsArray3 = soundsArray2.slice();
  let soundsArray4 = soundsArray.concat(soundsArray2, soundsArray3);


  //Randomize sounds
  for (let soundPosition = soundsArray4.length - 1; soundPosition >= 1; soundPosition--) {
    let numrandom = Math.floor(Math.random() * (soundPosition + 1));
    let sauve = soundsArray4[soundPosition];
    soundsArray4[soundPosition] = soundsArray4[numrandom];
    soundsArray4[numrandom] = sauve;
  }

  // console.log(soundsArray4);

  let p = -1;
  let numsnd;

  son();

  function son(evt) {

    // console.log('son evt;', evt);

    p++;
    if (p >= soundsArray4.length) {
      return;
    } else {
      let sonAjouer = document.getElementById(soundsArray4[p]);
      let snd = sonAjouer.getAttributeNode('id').value;
      numsnd = Number(snd.charAt(3));
      console.log('son playing sound snd:', snd);
      sonAjouer.play();
    } //fin du if
  } //fin de son

  let cells = document.getElementsByTagName('td');
  let nbreCells = cells.length;
  for (var y = 0; y < nbreCells; y++) {
    cells[y].addEventListener('click', donnerResultat);
  }

  function donnerResultat() {
    let idCell = "";
    let contenuCell = "";
    let numImage = 0;
    idCell = (this.id);
    contenuCell = document.getElementById(idCell).lastElementChild.getAttributeNode('id').value;
    numImage = Number(contenuCell.charAt(4));
    if (p >= soundsArray4.length) {
      return;
    }

    //Compares id soundn and id img cliqued
    if (numsnd === numImage) {
      reussitesArray.push(1);


      document.getElementById(idCell).style.backgroundColor = "#83f500";
      setTimeout(function() {
        document.getElementById(idCell).style.backgroundColor = "";
      }, 1000);


    } else {
      echecsArray.push(contenuCell);
      document.getElementById(idCell).style.backgroundColor = "#f13022";
      setTimeout(function() {
        document.getElementById(idCell).style.backgroundColor = ""
      }, 1000);
    } //fin du if

  } //end of function donnerResultat

  //next sound
  if (!sonListenersAdded) {
    // console.log('donnerResultat adding event listeners');
    for (let cell of cells) {
      cell.addEventListener('click', son, false);
    }
    sonListenersAdded = true;
  }

} //end of sonsAleatoires
*,
*:before,
*:after {
  margin: 0px;
  box-sizing: border-box;
}

html,
body {
  height: 100%;
  width: 100%;
}

body {
  justify-content: center;
  align-items: center;
  background-color: #ffeb3b63
}

h1 {
  font-size: 5vw;
  color: #FF5722;
}

.main {
  background-color: orange;
  width: 100%;
  position: relative;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
}

.card {
  position: relative;
  margin: auto;
}

.card img {
  max-height: 12vw;
  width: auto;
  position: relative;
  border-radius: 1em;
  margin: auto;
  border: 1px solid #9C27B0;
  cursor: pointer;
}

.buttons {
  width: 15%;
  position: absolute;
  top: 10vw;
}

.buttons ul {
  list-style: none;
}

#button1 {
  display: none;
}

#button,
#button1,
#button3,
#button4 {
  position: relative;
  max-height: 10vw;
  float: right;
}

table {
  margin: auto;
  width: 65%;
}

table,
td {
  border: 1px solid #9c27b0;
  //border-collapse: collapse;
  padding: 2px;
  text-align: center;
  font: 4vw bold;
  color: #FFC107;
  background-color: #d0e21b6e
}

td {
  width: 31%;
}

.cell {
  cursor: pointer;
  background-color: #795548a1
}

p {
  position: relative;
  color: blue;
  font-size: 4vw;
  left: 50px;
}
image
0 голосов
/ 28 мая 2020

Трудно сказать по предоставленному коду, но возможно ли, что вы продолжаете добавлять EventListeners каждый раз, когда воспроизводите звук, не удаляя их?

Может быть, вы можете удалить их после воспроизведения звука или только добавьте их один раз (где-нибудь вне функции son ()).

...