I'm refactoring a vanilla JS Wheel of Fortune/Hangman game and I'm trying to figure out how to remove the previous node elements displayed in the underscores representing the letters in the word the user is trying to guess. If the user picks a word that's 5-6 letters, that usually fine because the next random word is probably more than 5-6 letters so it will overwrite the shorter array of underscores. My problem is, a word like "JAVASCRIPT", causes problems. If the user gets "ARRAYS", the "RIPT" from the previous "JAVASCRIPT" remains on the page. I tried several things like window.location.reload(), but I don't want to reload the page each time the user guesses the word correctly since I want to add a point-based system. I tried wordDisplay.remove() but no luck. Lastly, I tried
wordDisplay.childNodes.forEach(child => {
wordDisplay.removeChild(child);
});
but this doesn't allow the underscores to show once the play button is hit. It also doesn't completely solve the problem of resetting the childNodes in wordDisplay. Any ideas how I can fix this problem?
let guessesLeft,
letterClicked,
wordChoice,
remainingLetters,
answerList = [],
wordArray = ["JAVASCRIPT", "ARRAYS", "FUNCTIONS", "HOISTING", "RECURSION", "EVENTS", "KEYUP", "TERNARY"],
hint = document.querySelector(".hint"),
letterGuessed = document.querySelector("#your-guess"),
numbers = document.querySelector("#numbers"),
guesses = document.querySelector("#guesses"),
wordDisplay = document.querySelector("#words"),
letterCount = document.querySelector(".letters"),
newGame = document.querySelector("#play"),
letterBoxes = document.querySelector("#alphabet"),
titleHeader = document.querySelector(".welcome"),
pointTotal = document.querySelector("#pointTotal");
function playGame() {
guessesLeft = 6;
guesses.innerHTML = `You have ${guessesLeft} guesses left`;
// Pick a random word.
wordChoice = wordArray[Math.floor(Math.random() * wordArray.length)];
for (var i = 0; i < wordChoice.length; i++) {
answerList[i] = "_";
}
// Display underscores on page representing each letter in the random word
wordDisplay.innerHTML = answerList.join('');
let hintObject = {
JAVASCRIPT: "The language of the web",
ARRAYS: "Similar to objects",
FUNCTIONS: "Stores instructions",
HOISTING: "Moving declarations to the top",
RECURSION: "Calling functions inside of functions",
EVENTS: "This happens to HTML elements; like a concert",
KEYUP: "Not 'keydown', but...",
TERNARY: "Type of operator"
}
hint.innerHTML = `Clue: ${hintObject[wordChoice]}`;
// Display number of letters in the random word on the page
remainingLetters = wordChoice.length;
letterCount.innerHTML = `The word is ${remainingLetters} letters long`;
// wordDisplay.childNodes.forEach(child => {
// wordDisplay.removeChild(child);
// });
}
// Register the player’s guess.
function buttonPress(e) {
letterClicked = e.target.textContent;
letterGuessed.innerHTML = `You guessed the letter ${letterClicked}`;
matchWord(letterClicked);
}
// Pass the letter event from buttonPress into the randomWord function
function matchWord(letter) {
pointTotal = 0;
if (remainingLetters > 0) {
let foundMatch = false;
for (var i = 0; i < wordChoice.length; i++) {
if (wordChoice[i] === letter) {
foundMatch = true;
answerList[i] = letter;
wordDisplay.innerHTML = answerList.join(' ');
remainingLetters--;
}
}
if (!foundMatch) {
guessesLeft--;
guesses.innerHTML = (`You have ${guessesLeft} guesses left`);
}
if (guessesLeft === 0) {
hint.innerHTML = "Sorry, you're out of guesses!";
setTimeout(function () {
hint.innerHTML = "If you'd like to play again, click the spin button.";
letterCount.innerHTML = "You lost :(";
}, 3000);
}
if (remainingLetters === 0) {
hint.innerHTML = "Great job! You guessed it!";
pointTotal++;
setTimeout(function () {
playGame();
}, 3000);
}
}
}
body {
background: linear-gradient(200deg, #025302, #027740, #05b965, #07e07b, #05532f);
background-size: contain;
color: white;
font-family: 'Merriweather', serif;
text-shadow: 2px 2px 3px rgb(27, 22, 22);
}
#container {
display: block;
margin: 20px;
}
#roundsWon {
margin-left: 15%;
font-size: 45px;
}
.welcome {
font-size: 80px;
letter-spacing: 5px;
text-align: center;
}
.letters, .lives {
font-size: 30px;
text-align: center;
}
.hint {
font-size: 35px;
text-align: center;
}
#words {
justify-content: center;
text-align: center;
font-size: 50px;
margin: 10px;
letter-spacing: 20px;
}
#alphabet {
margin: 0 auto;
width: 990px;
}
#letterChoices {
padding: 5px;
margin: 5px;
width: 2em;
height: 10%;
font-size: 2em;
border: 2px solid white;
text-align: center;
box-shadow: 2px 2px 3px black;
}
#play {
float: left;
margin: 20px auto;
font-size: 60px;
}
#your-guess {
float: right;
margin-right: 5%;
font-size: 40px;
color: #bada55;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Wheel of Fortune</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<link rel="stylesheet" href="main.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<link href="https://fonts.googleapis.com/css?family=Merriweather" rel="stylesheet">
</head>
<body>
<div class="Title">
<h1 class="welcome">Welcome to Wheel of Fortune!</h1>
</div>
<div id="alphabet" onclick="buttonPress(event)">
<a id="letterChoices" class="waves-effect waves-light btn-large">A</a>
<a id="letterChoices" class="waves-effect waves-light btn-large">B</a>
<a id="letterChoices" class="waves-effect waves-light btn-large">C</a>
<a id="letterChoices" class="waves-effect waves-light btn-large">D</a>
<a id="letterChoices" class="waves-effect waves-light btn-large">E</a>
<a id="letterChoices" class="waves-effect waves-light btn-large">F</a>
<a id="letterChoices" class="waves-effect waves-light btn-large">G</a>
<a id="letterChoices" class="waves-effect waves-light btn-large">H</a>
<a id="letterChoices" class="waves-effect waves-light btn-large">I</a>
<a id="letterChoices" class="waves-effect waves-light btn-large">J</a>
<a id="letterChoices" class="waves-effect waves-light btn-large">K</a>
<a id="letterChoices" class="waves-effect waves-light btn-large">L</a>
<a id="letterChoices" class="waves-effect waves-light btn-large">M</a>
</br>
<a id="letterChoices" class="waves-effect waves-light btn-large">N</a>
<a id="letterChoices" class="waves-effect waves-light btn-large">O</a>
<a id="letterChoices" class="waves-effect waves-light btn-large">P</a>
<a id="letterChoices" class="waves-effect waves-light btn-large">Q</a>
<a id="letterChoices" class="waves-effect waves-light btn-large">R</a>
<a id="letterChoices" class="waves-effect waves-light btn-large">S</a>
<a id="letterChoices" class="waves-effect waves-light btn-large">T</a>
<a id="letterChoices" class="waves-effect waves-light btn-large">U</a>
<a id="letterChoices" class="waves-effect waves-light btn-large">V</a>
<a id="letterChoices" class="waves-effect waves-light btn-large">W</a>
<a id="letterChoices" class="waves-effect waves-light btn-large">X</a>
<a id="letterChoices" class="waves-effect waves-light btn-large">Y</a>
<a id="letterChoices" class="waves-effect waves-light btn-large">Z</a>
</div>
<div id="container">
<div id="header">
<p class="hint">Hint will display once you spin</p>
<!-- The letters will be tied to the number of letters in the random array -->
<p class="letters">The word is <span id="numbers">_</span> letters long</p>
<!-- The user will be given a number of choices and with each wrong choice, they lose a turn -->
<p class="lives"><span id="guesses">You have _ guesses remaining</span></p>
<p id="words"></p>
</br>
<a id="play" onclick="playGame()" class="waves-effect waves-light btn-large">Spin</a>
<span id="roundsWon">Rounds won:<span id="pointTotal"></span></span>
<span id="your-guess">Letter guessed</span>
</div>
</div>
<script src="main.js"></script>
</body>
</html>
You need to reset your values after every
setTimeout(function () {
answerList = [];
letterClicked = '';
playGame();
}, 3000);
As currently your array keeps the letters and you overwrite only some of them and also you keep the last clicked letter.