WHAT IS HANGMAN
In this article, we will learn how to build Hangman in Javascript. Where one player enters a word and its topic and starts the game. The other player tries to guess the word by typing in the letter with a certain number of guesses
If you’re still not sure about the game, and its rule, you can take a look at it here
You can install python from the link given below for running the codes
https://www.python.org/downloads/
SOURCE CODE
If you want to try the code right away, we’ll help you out with that, but I’d also suggest you learn the explanation below on how to build Hangman in Javascript/HTML/CSS
1. OPEN YOUR CODE EDITOR

You can use any code editor, but I will be using Visual Studio Code here, and I’d recommend you to use that too. But once again, it’s all up to you!
2. CREATE / OPEN A FOLDER

This is where we’ll have all our files – index.html, styles.css, and script.js
3. ADD FILES

Let’s create our files, index.html – for the page, styles.css – for stylings, and script.js – to get our game running. Once you’ve finished that, let’s start adding our codes for Hangman in Javascript/HTML/CSS
4. THE CODE
We have to paste this code into the index.html file and save it
<!DOCTYPE html>
<html>
<head>
<title>Hangman in Javascript</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<link rel="stylesheet" href="styles.css">
<script src="script.js" defer></script>
</head>
<body>
<div id = "query">
<div class="mb-3">
<label for="formGroupExampleInput" class="form-label">Word:</label>
<input type="text" class="form-control" id="formGroupExampleInput" value="" placeholder="Enter the Word">
</div>
<div class="mb-3">
<label for="formGroupExampleInput2" class="form-label">Topic</label>
<input type="text" class="form-control" id="formGroupExampleInput2" placeholder="Enter the Topic" value="">
</div>
<button type="button" class="btn btn-primary" id = "sbtn">Start</button>
</div>
<div id = "game">
<h3 style="color: rgb(102, 102, 102);">Guess the Word</h3>
<h4 id="topic">Topic: Undefined</h4>
<br>
<h1 id="text"></h1>
<br><br>
<div class="mb-3" style="white-space: nowrap">
<label for="formGroupExampleInput" class="form-label" style="display: inline-block;">Your Guess</label>
<input type="text" class="form-control" id="formGroupExampleInput3" style="width: 5vh;display: inline-block;" maxlength="1">
<button type="button" class="btn btn-primary" style="display: inline-block;" id="guess">Guess</button>
</div>
<span style="display: inline-flex;">
<h4>Lives: </h4>
<h4 id ="lives">♥♥♥♥♥♥</h4>
</span>
<br>
<span style="display: inline-flex;">
<h4>Mistakes: </h4>
<h4 id ="mistakes" style="color: red;"></h4>
</span>
</div>
<div style="color: green; display: none;" id='won'>
<h1>YOU GUESSED IT!</h1>
<h3 id = 'answer_won' style="color: black;"></h3>
<button type="button" class="btn btn-primary" style="display: inline-block;" id="newgamew" onclick="locationreload()"> New Game</button>
</div>
<div style="color: rgb(197, 23, 23); display: none;" id='lost'>
<h1>YOU LOSE!</h1>
<h3 style="color:black" id = 'answer_lost'></h3>
<button type="button" class="btn btn-primary" style="display: inline-block;" id="newgamel" onclick="reload()">Play Again</button>
</div>
</body>
</html>
After that, jump over to the styles.css and paste this code
body {
margin : 10vh 10vh 10vh 0vh;
display: flex;
justify-content: center;
}
#formGroupExampleInput, #formGroupExampleInput2 {
width:50vh;
}
#query {
display: inline-block;
}
#game {
display: none;
}
#text {
font-size: 8vh;
}
When you’re done with that, go to script.js and paste this
document.addEventListener('DOMContentLoaded', function(){
var lives = 6
var query = document.querySelector('#query')
var game = document.querySelector('#game')
var word = document.querySelector('#formGroupExampleInput')
var topic = document.querySelector('#formGroupExampleInput2')
var sbtn = document.querySelector('#sbtn')
sbtn.disabled = true
word.onkeyup = enable;
topic.onkeyup = enable;
function enable() {
if (word.value != '' && topic.value != ''){
sbtn.disabled = false
} else {
sbtn.disabled = true
}
}
document.querySelector('#sbtn').onclick = assign;
document.querySelector('#guess').onclick = guess;
var st = ''
var hashed = ''
function assign() {
query.style.display = "none";
game.style.display = "inline-block";
for (let i of word.value){
st += i.toUpperCase()
st += ' '
}
for (let i of st) {
if ('AEIOU '.includes(i)){
hashed += i
}else {
hashed += '_'
}
}
document.querySelector('#topic').innerHTML = `Topic : ${topic.value}`
document.querySelector('#text').innerHTML = hashed
}
function guess() {
hashed = document.querySelector('#text').innerHTML
hashed2 = hashed
var gl = document.querySelector('#formGroupExampleInput3').value.toUpperCase()
if (st.includes(gl)){
for (i in st){
if (gl == st[i]){
j = Math.ceil(i/2)
hashed = hashed.split(' ')
hashed[j] = gl
hashed = hashed.join(' ')
}
}
}else {
lives --;
document.querySelector('#lives').innerHTML = '♥'.repeat(lives)
document.querySelector('#mistakes').innerHTML += gl+' '
}
document.querySelector('#text').innerHTML = hashed
document.querySelector('#formGroupExampleInput3').value = ''
if (lives<=0){
game.style.display = "none";
document.querySelector('#lost').style.display = "inline-block"
document.querySelector('#answer_lost').innerHTML ="THE WORD WAS " + word.value.toUpperCase()
} else if(st == hashed){
game.style.display = "none";
document.querySelector('#won').style.display = "inline-block"
document.querySelector('#answer_won').innerHTML ="THE WORD WAS " + word.value.toUpperCase()
}
}
document.querySelector('#newgamel').onclick = reload
document.querySelector('#newgamew').onclick = reload
function reload() {
location.reload();
}
})
RUNNING THE GAME

Now let’s run our Hangman in Javascript. To do that, you can either try opening the index.html using your web browser. Or install Visual Studio’s Live Server Extension

Great! Now let’s play the game

Let’s try entering a word, for instance, California, and the topic, obviously, City. Now, click start

Now let’s go ahead and guess some letters. First, let us try “C” since we already know “CALIFORNIA” includes “C”.

Cool! We see “C” up there, so let us try some other letter that isn’t in the word CALIFORNIA, like, Z for example

You can see that Z gets added among the mistakes. If you notice carefully, you can also see the number of lives has been reduced by one

If we manage to win, by guessing the word, we get this message

Otherwise, if we failed to do that, we get back this
EXPLANATION
INDEX.HTML
First, we create a basic HTML page, with 4 div
- A Section where the first player enters the word to be guessed, along with its topic
- The game itself, where there’s an h1 that shows a half-revealed version of the word entered in the previous div text field and button, and an h4 that displays the number of lives left
- Congratulations Message that is displayed when the player guesses the word correctly
- A try again message if the player ran out of lives
HEAD
<!DOCTYPE html>
<html>
<head>
<title>Hangman in Javascript</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<link rel="stylesheet" href="styles.css">
<script src="script.js" defer></script>
</head>
<body>
</body>
</html>
Line4: We give a title, Hangman in Javascript
5: After that, we import Bootstrap, for better styling
7: And then, we import styles.css, the CSS file we created for the stylings
8: Finally, we create the <script>
tag and link it to the script.js file using the src
attribute
Note
We use href
for linking CSS stylesheets, and src
for linking JavaScript files, they can be pretty confusing
DIV TO ENTER WORD
<!-- <!DOCTYPE html>
<html>
<head>
<title>Hangman</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<link rel="stylesheet" href="styles.css">
<script src="script.js" defer></script>
</head>
<body> -->
<div id = "query">
<div class="mb-3">
<label for="formGroupExampleInput" class="form-label">Word:</label>
<input type="text" class="form-control" id="formGroupExampleInput" value="" placeholder="Enter the Word">
</div>
<div class="mb-3">
<label for="formGroupExampleInput2" class="form-label">Topic</label>
<input type="text" class="form-control" id="formGroupExampleInput2" placeholder="Enter the Topic" value="">
</div>
<button type="button" class="btn btn-primary" id = "sbtn">Start</button>
</div>
<!-- </body>
</html> -->
Line 11: We create a div and give it an id query
, so that we’ll be able to hide and show it whenever we want

12-21: Inside that div, we just copy/paste the input fields from Bootstrap, and edit it to our needs. You can find the code for the form here
22: Finally we finish it by adding the Start Button with id as sbtn
GAME DIV
<!-- <!DOCTYPE html>
<html>
<head>
<title>Hangman</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<link rel="stylesheet" href="styles.css">
<script src="script.js" defer></script>
</head>
<body> -->
<!-- <div id = "query">
<div class="mb-3">
<label for="formGroupExampleInput" class="form-label">Word:</label>
<input type="text" class="form-control" id="formGroupExampleInput" value="" placeholder="Enter the Word">
</div>
<div class="mb-3">
<label for="formGroupExampleInput2" class="form-label">Topic</label>
<input type="text" class="form-control" id="formGroupExampleInput2" placeholder="Enter the Topic" value="">
</div>
<button type="button" class="btn btn-primary" id = "sbtn">Start</button>
</div> -->
<div id = "game">
<h3 style="color: rgb(102, 102, 102);">Guess the Word</h3>
<h4 id="topic">Topic: Undefined</h4>
<br>
<h1 id="text"></h1>
<br><br>
<div class="mb-3" style="white-space: nowrap">
<label for="formGroupExampleInput" class="form-label" style="display: inline-block;">Your Guess</label>
<input type="text" class="form-control" id="formGroupExampleInput3" style="width: 5vh;display: inline-block;" maxlength="1">
<button type="button" class="btn btn-primary" style="display: inline-block;" id="guess">Guess</button>
</div>
<span style="display: inline-flex;">
<h4>Lives: </h4>
<h4 id ="lives">♥♥♥♥♥♥</h4>
</span>
<br>
<span style="display: inline-flex;">
<h4>Mistakes: </h4>
<h4 id ="mistakes" style="color: red;"></h4>
</span>
</div>
<!-- </body>
</html> -->
Line 24: We create a div and give it an id game
, so that we’ll be able to hide and show it whenever we want
26: For now, let’s leave it “Topic: Undefined”. Later on, we use javascript to manipulate the word after “Topic: “
28: Now, we add an empty h2 with the id text, since this will be the place where we display an incomplete version of the word to be guessed

30-37: In this div, we have a label, text input and a submit button, where the user makes his/her guess

38-47: Finally, we add 2 spans, one that keeps track of the number of lives left, and then other for keeping track of the mistakes. For now, we leave it 6 lives and no mistakes(empty)
WIN/LOSE MESSAGE
<!-- <!DOCTYPE html>
<html>
<head>
<title>Hangman</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<link rel="stylesheet" href="styles.css">
<script src="script.js" defer></script>
</head>
<body>
<div id = "query">
<div class="mb-3">
<label for="formGroupExampleInput" class="form-label">Word:</label>
<input type="text" class="form-control" id="formGroupExampleInput" value="" placeholder="Enter the Word">
</div>
<div class="mb-3">
<label for="formGroupExampleInput2" class="form-label">Topic</label>
<input type="text" class="form-control" id="formGroupExampleInput2" placeholder="Enter the Topic" value="">
</div>
<button type="button" class="btn btn-primary" id = "sbtn">Start</button>
</div>
<div id = "game">
<h3 style="color: rgb(102, 102, 102);">Guess the Word</h3>
<h4 id="topic">Topic: Undefined</h4>
<br>
<h1 id="text"></h1>
<br><br>
<div class="mb-3" style="white-space: nowrap">
<label for="formGroupExampleInput" class="form-label" style="display: inline-block;">Your Guess</label>
<input type="text" class="form-control" id="formGroupExampleInput3" style="width: 5vh;display: inline-block;" maxlength="1">
<button type="button" class="btn btn-primary" style="display: inline-block;" id="guess">Guess</button>
</div>
<span style="display: inline-flex;">
<h4>Lives: </h4>
<h4 id ="lives">♥♥♥♥♥♥</h4>
</span>
<br>
<span style="display: inline-flex;">
<h4>Mistakes: </h4>
<h4 id ="mistakes" style="color: red;"></h4>
</span>
</div> -->
<div style="color: green; display: none;" id='won'>
<h1>YOU GUESSED IT!</h1>
<h3 id = 'answer_won' style="color: black;"></h3>
<button type="button" class="btn btn-primary" style="display: inline-block;" id="newgamew" onclick="locationreload()"> New Game</button>
</div>
<div style="color: rgb(197, 23, 23); display: none;" id='lost'>
<h1>YOU LOSE!</h1>
<h3 style="color:black" id = 'answer_lost'></h3>
<button type="button" class="btn btn-primary" style="display: inline-block;" id="newgamel" onclick="reload()">Play Again</button>
</div>
<!-- </body>
</html> -->
Line 50 and 56: We create a div and give it an id win
and lost respectively, so that we’ll be able to hide and show it whenever we want

52 and 58: This Empty h3 tag can later be used to display the word that was guessed by the player. This can be easily achieved using JavaScript
53 and 59: Now, we create a New Game button, that would reload the page when clicked, taking us back to the beginning of the game
And with that, we’re done with the HTML part of the code. Now that our index.html is let’s move on with some stylings
STYLES.CSS
body {
margin : 10vh 10vh 10vh 0vh;
display: flex;
justify-content: center;
}
#formGroupExampleInput, #formGroupExampleInput2 {
width:50vh;
}
#query {
display: inline-block;
}
#game {
display: none;
}
#text {
font-size: 8vh;
}
Well, since most of our stylings have been taken care of by bootstrap, there’s very little need for our own CSS stylings
body: Using these CSS stylings we bring the whole game to the center of the page
#formGroupExampleInput, #formGroupExampleInput2: We give it a width of 50vh to give us more space when entering the word to be guessed and its topic
#query: We keep its display inline-block since it is the part of the page that has to be shown when the user first enters the game
#text: Let’s have a font size of 8vh, for the incomplete version of the word that has to be guessed
Cool! We just completed the CSS part of the code, now we focus on building the functionalities for our Hangman in javascript
SCRIPT.JS
First, we define an event listener that runs when the page has loaded completely(DOMContentLoaded)
Inside that event listener, we define
- All the variables required
enable()
, a function using which we allow the user to start the game only if the word isn’t empty, by enabling and disabling the Start buttonassign()
function that would store the real word in the variable st, iterates through the word a store a hashed version of the word in a variablehashed
that displays “_” instead of all consonants(non-vowels)guess()
function that will be called when the player enters a guess. This function would check if the word includes that guessed letter, if it does, all the letters from the word that match the guess would be revealed. Otherwise, the number of lives would reduce by one, and the letter would be added to the mistakes sectionreload()
function reloads the page when we click New Game or Try Again
VARIABLES
document.addEventListener('DOMContentLoaded', function(){
var lives = 6
var query = document.querySelector('#query')
var game = document.querySelector('#game')
var word = document.querySelector('#formGroupExampleInput')
var topic = document.querySelector('#formGroupExampleInput2')
})
Line 1: Event Listener that waits for the page to load completely
2: Variable that stores the number of lives, let’s keep it 6, for instance
4,5: The Query and the Game sections are each stored in a variable. You can do this using the JavaScript Selectors, if you’re not sure about selectors, you can always check it out from our site here

7,8: Remember these input fields? We are gonna store their values inside the variables word
and topic respectively
ENABLE()
// document.addEventListener('DOMContentLoaded', function(){
// var lives = 6
// var query = document.querySelector('#query')
// var game = document.querySelector('#game')
// var word = document.querySelector('#formGroupExampleInput')
// var topic = document.querySelector('#formGroupExampleInput2')
var sbtn = document.querySelector('#sbtn')
sbtn.disabled = true
word.onkeyup = enable;
topic.onkeyup = enable;
function enable() {
if (word.value != '' && topic.value != ''){
sbtn.disabled = false
} else {
sbtn.disabled = true
}
}
// })
Line 10: Stores the start button element() in the variable sbtn
11: Let’s keep the button disabled by default
13,14: Now, whenever we find the user typing in something into either of the text fields, we call the enable()
function
16-21: What the enable()
function does is that it checks if the value inside the text field is not null if it is null the button is disabled, otherwise it will be enabled
ASSIGN()
// document.addEventListener('DOMContentLoaded', function(){
// var lives = 6
// var query = document.querySelector('#query')
// var game = document.querySelector('#game')
// var word = document.querySelector('#formGroupExampleInput')
// var topic = document.querySelector('#formGroupExampleInput2')
// var sbtn = document.querySelector('#sbtn')
// sbtn.disabled = true
// word.onkeyup = enable;
// topic.onkeyup = enable;
// function enable() {
// if (word.value != '' && topic.value != ''){
// sbtn.disabled = false
// } else {
// sbtn.disabled = true
// }
// }
document.querySelector('#sbtn').onclick = assign;
var st = ''
var hashed = ''
function assign() {
query.style.display = "none";
game.style.display = "inline-block";
for (let i of word.value){
st += i.toUpperCase()
st += ' '
}
for (let i of st) {
if ('AEIOU '.includes(i)){
hashed += i
}else {
hashed += '_'
}
}
document.querySelector('#topic').innerHTML = `Topic : ${topic.value}`
document.querySelector('#text').innerHTML = hashed
}
// })
Line 24: We give the submit button in the query div an onclick event, so that when the button has clicked the assign() function is run
25,26: We create 2 variables, st and hashed that create a real and hashed version of the word to be guessed, for the hashed version of the word, it displays “_” for letters apart from vowels
For instance: If the word is California, st is gonna be C A L I F O R N I A, and hashed is gonna be _ A _ I _ O _ _ I A, where the letters that are replaced by underscores are expected to be guessed by the player
28,29: Here, since the button has been clicked, and the function is run, inside the function, this part of the code is used to hide the query div and unhide the game div, since we’ve started with the game
30-33: In the first for loop we create the st
a version of the original word by iterating through the value in the input field of the word from the previous div
34-39: Now since we got the st version of the word, with uppercase and spaces in between, the second for loop iterates through st and turns all the non-vowels into “_” and stores it in the variable hashed
41,42: This part of the code replaces the value in the h3 with id topic with the new topic given by the player, and the value in the h3 with id text with the value of hashed
GUESS()
// document.addEventListener('DOMContentLoaded', function(){
// var lives = 6
// var query = document.querySelector('#query')
// var game = document.querySelector('#game')
// var word = document.querySelector('#formGroupExampleInput')
// var topic = document.querySelector('#formGroupExampleInput2')
// var sbtn = document.querySelector('#sbtn')
// sbtn.disabled = true
// word.onkeyup = enable;
// topic.onkeyup = enable;
// function enable() {
// if (word.value != '' && topic.value != ''){
// sbtn.disabled = false
// } else {
// sbtn.disabled = true
// }
// }
// document.querySelector('#sbtn').onclick = assign;
// var st = ''
// var hashed = ''
// function assign() {
// query.style.display = "none";
// game.style.display = "inline-block";
// for (let i of word.value){
// st += i.toUpperCase()
// st += ' '
// }
// for (let i of st) {
// if ('AEIOU '.includes(i)){
// hashed += i
// }else {
// hashed += '_'
// }
// }
// document.querySelector('#topic').innerHTML = `Topic : ${topic.value}`
// document.querySelector('#text').innerHTML = hashed
// }
document.querySelector('#guess').onclick = guess;
function guess() {
hashed = document.querySelector('#text').innerHTML
hashed2 = hashed
var gl = document.querySelector('#formGroupExampleInput3').value.toUpperCase()
if (st.includes(gl)){
for (i in st){
if (gl == st[i]){
j = Math.ceil(i/2)
hashed = hashed.split(' ')
hashed[j] = gl
hashed = hashed.join(' ')
}
}
}else {
lives --;
document.querySelector('#lives').innerHTML = '♥'.repeat(lives)
document.querySelector('#mistakes').innerHTML += gl+' '
}
document.querySelector('#text').innerHTML = hashed
document.querySelector('#formGroupExampleInput3').value = ''
if (lives<=0){
game.style.display = "none";
document.querySelector('#lost').style.display = "inline-block"
document.querySelector('#answer_lost').innerHTML ="THE WORD WAS " + word.value.toUpperCase()
} else if(st == hashed){
game.style.display = "none";
document.querySelector('#won').style.display = "inline-block"
document.querySelector('#answer_won').innerHTML ="THE WORD WAS " + word.value.toUpperCase()
}
}
// })
Line 45: Now we make sure that whenever the guess button is clicked, we run the guess function
48: We create a copy of the variable and store it in a new variable hashed2

49: The value of the letter entered by the player is stored in the variable gl
50-59: If the letter entered is in the word to be guessed, we replace the underscores with the letter at the Appropriate positions
59-63: If that’s not the case, then reduce the lives by 1, add the letter to the list of mistakes, and also display the hearts accordingly
64,65: We update the hashed version of the word shown and then clear the input field
67-71 and 71-75: If the player runs out of lives, the try again div is shown, if the player guesses the word, the winner div is shown


RELOAD()
document.querySelector('#newgamel').onclick = reload
document.querySelector('#newgamew').onclick = reload
function reload() {
location.reload();
}
If either of the play again buttons are clicked from the try again and winner divs, the page reloads, to do this we use the function location.reload()
TO SUM UP . . .
Today we have seen how to build Hangman in Javascript. If you have any questions or feedback on this, feel free to post in the comments section below.
If you are on your way to becoming a Javascript developer, you might find our site really helpful. Hit this link for more JavaScript related posts
Or if you’re interested in Game Development, you can follow this link
Check it out, it’s Simply the Best Code