Onclick continue de revenir à sa valeur d'origine

Essayais de faire un dragage de mines en javascript et rencontré ce problème …

J'ai créé une table et chaque td est une "boîte" avec une mine ou rien (Actuellement). Après avoir cliqué sur une boîte, le javascript devrait changer l'onclick de "clicked (this.id)" à une alerte qui indique "NOPE" (a fait une alerte juste pour tester si quelque chose se passait), mais ce qui se passe:

  1. Je clique sur "case 1", il révèle ce qu'il y a (bombe ou rien)
  2. Je clique dessus, cette fois je reçois une alerte "NOPE" – ce qui signifie que l'onclick a changé. Bien!
  3. Je clique sur "case 2", il révèle ce qu'il y a (bombe ou rien)
  4. Je clique dessus, cette fois je reçois une alerte "NOPE" – ce qui signifie que cet onclick a changé aussi!
  5. Je clique à nouveau sur "case 1". Le clic (this.id) s'exécute à nouveau. (Ceci est montré parce que j'ai ajouté un compteur pour chaque fois que la fonction s'exécute)

Pour une raison quelconque, onclick revient à sa valeur d'origine (cliqué (this.id)).

J'ai fait une page de test, une table avec 2 td et la même pensée à l'esprit (changez la valeur de clic après avoir cliqué) et ça marche … Je n'ai aucune idée de la façon de résoudre ce problème …

Le test.html qui fonctionne: http://pastebin.com/62ayRJps

Le HTML du site ne fonctionne pas comme prévu: http://pastebin.com/SZ6NU8j9

Et le Javascript du site qui ne fonctionne pas comme prévu: http://pastebin.com/bevJHNLc

Vos gestionnaires d'événements de clic sont en cours de réinitialisation en raison de cette ligne en clicked(id) :

 document.getElementById("minesweeper").innerHTML += ammountClicked+" - " 

Chaque cellule de table a un onclick='clicked(this.id);' Attribut dans son HTML. Lorsque vous affectez votre fonction de test tst à l'objet DOM de la cellule de table, vous définissez la propriété onclick de l'objet DOM, mais cela ne modifie pas l'attribut onclick du HTML. (Oui, c'est déroutant.)

Dans la ligne de code ci-dessus, le navigateur lit le innerHTML partir du innerHTML de mines div (qui a les attributs d' onclick origine), le concatène avec une autre chaîne, puis réattribue le résultat à la division des div . Cela efface le contenu original du div et le remplace par le nouveau HTML (une table où chaque cellule possède l'attribut onclick origine).


Si vous souhaitez avoir une zone de message, je suggère de définir innerHTML sur un autre élément: Demo

Dans la démo, j'ai changé la ligne 49 (ajout d'un span ):

 print += "</table><span id='message'></span>"; 

Et la ligne 107 (affectation du texte à la span ):

 document.getElementById("message").innerHTML += ammountClicked+" - "; 

Je vous suggère de suivre l'état de chaque article. Il est préférable de ne pas modifier le code lors de l'exécution de votre application.

 var states = {1: 0, 2: 0}; function clicked(id) { if (states[id] === 0) alert("First time clicking me, eh?"); else alert("Seems we have a repeat offender!"); states[id]++; } 

Cela vous permet de diviser la logique dans votre fonction en vérifiant si l' state d'un id donné a été modifié (par exemple, par un clic précédent).

Démo interactive sur jsbin

Avec quelques modifications dans la function clicked(id) cela peut fonctionner:

  1. Ligne de commentaire //document.getElementById(id).onclick = tst;
  2. Ajouter un field[row][column] = false; À la fin de la fonction
  3. Vérifiez si le champ contient false avant d'effectuer des actions:

     if (field[row][column] == false) { console.log("This cell has already been clicked"); return; } 

Il n'est pas nécessaire de changer les événements surcliquer.

Le problème, tel qu'expliqué par Jeffery To, est le suivant:

  1. Vous cliquez sur la cellule 0,0
  2. La fonction clicked s'appelle
  3. minesweeper.innerHTML = minesweeper.innerHTML + "1 - " [tous les événements onclick ont ​​été réinitiés]
  4. Onclic événement de la cellule 0,0 est changé
  5. Vous cliquez sur une nouvelle cellule, 0,1 par exemple
  6. minesweeper.innerHTML = minesweeper.innerHTML + "2 - " [tous les événements onclick ont ​​été réinitiés]
  7. Onclick event of cell 0,1 est changé

Les événements onclick sont réinitialisés car innerHTML contient toutes les déclarations onclick. C'est comme réécrire tout le code HTML de cette div, et ainsi réécrire tous les éléments enfants et ses événements. C'est aussi la raison pour laquelle votre exemple simple (celui avec seulement deux cellules) fonctionne.