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:
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:
//document.getElementById(id).onclick = tst;
field[row][column] = false;
À la fin de la fonction 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:
clicked
s'appelle minesweeper.innerHTML = minesweeper.innerHTML + "1 - "
[tous les événements onclick ont été réinitiés] minesweeper.innerHTML = minesweeper.innerHTML + "2 - "
[tous les événements onclick ont été réinitiés] 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.