I am making a variation of a hangman game. I have the random word generator give me a word in the phrase variable and then the passPhrase variable breaks it into an array. I want the keydown function to compare the key pressed to the array and record the string if it is correct in the HTML
which is grabbed by the secretWord variable. The problem I am having is that the string will show when pressed correctly but disappears on the next keydown event. I also have a HTML
tag to show missed guesses grabbed by the variable pastGuess. it is showing every keydown event.
let phrase = generate(1);
let passPhrase = phrase[0].split('');
window.addEventListener('keydown', function(event){
for (let i=0; i < passPhrase.length; i++){
if (event.key === passPhrase[i]) {
secretWord.textContent = passPhrase[i];
} else if (event.key != passPhrase[i]) {
pastGuess.textContent = event.key;
}
}
});
I am not sure why the if / else statement isnt preventing correct guesses from showing up in the pastGuess variable. I also have no clue how to go about getting the correct guesses to stay visible
2
Answers
Try manually tracing through the execution of your for loop. If
event.key
is one of the letters inpassPhrase
, then on one of the iterations,event.key
will equalpassPhrase[i]
andsecretWord
will get set to the letter. But on every other iteration,event.key != passPhrase[i]
, so the else statement will setpastGuess
to the same letter. EDIT: This is whypastGuess
shows every key you press, even when the letter is correct and shouldn’t show up. Try to think of how to change the loop and the if/else to not do this. Maybe don’t setsecretWord
orpastGuess
until you’ve finished looping so you can decide which one to modify.When you say
secretWord
"disappears" on the next keydown, do you mean that if you press an incorrect letter, the text insecretWord
fully disappears? Or that if you press another correct letter, the text insecretWord
gets replaced with the new letter? InsecretWord.textContent = passPhrase[i]
, you are setting the whole content of the element to only the new letter, not adding the new letter to existing content.EDIT:
Just setting
htmlElement.textContent = ...
will reset the whole contents of the element. Since you want to add to what’s already there, it’s probably best to keep track of everything purely in JS (in an array/object/etc; this is called your state), then whenever anything changes, update the HTML (more accurately, the DOM) accordingly in a function you might call render.You basically have to remember which letters have been guessed yet and which ones haven’t. You could try using
array.map
at the start to makepassPhrase
be an array of objects, each one looking like{ letter: 'a', guessed: false }
. On each keydown, set each matching object in passPhrase to havepassPhrase[i].guessed = true
. Then callrender
whenever you change your state.render
can usearray.map
to turn each object into a string: either the letter if it has been revealed by the user, or a placeholder if it has not been guessed yet. Then usejoin
to turn that into one string to put in a DOM element.To display every new incorrect guess in addition to the old ones, you’ll have to keep another piece of state: an array of past incorrect guesses. Similarly in
render
, map or join that into text to put in a DOM element.you are updating
secretWord.textContent
andpastGuess.textContent
inside the loop for every character in thepassPhrase
. This caused correct guesses to overwrite each other, and incorrect guesses to be displayed on each key press.