I am working on a numbers click game. The idea of the game is you get a random pattern of numbers and you have to click those numbers in order (this hasn't been implemented yet). Game also has a function for random numbers, random colors and random font sizes.
I have 2 questions:
If you look at my comments in JS file, basically I created a variable called
timeInterval
for mysetInterval
function. When you scroll down to the bottom, in myresetBtn.EventListener
, I am able toclearInterval(timeInterval)
and it works.
Why does this work?
I thought in order for this to work, first I would have to declaretimeInterval
as a global var or let variable in the global scope? The fact that its inside mystartGame()
function and I am able to execute it in myresetBtn.EventListener
function doesn't register with me. How am I executing it without it being declared globally? What am I missing?I am working on my reset button at the moment. I am trying to reset all my numbers either to 0 or to a blank state in all of my squares (I also want to do that to font, color etc). From my understanding in order to do that I need to take
squares[i].textContent
and set that to 0. Being thatsquares[i].textContent
is inside a loop of myrandomNumber()
function, I'm having a hard to of how I can access that property.
Sorry for so much writing, I tried to put my thoughts out there so maybe someone can catch an error in my thinking or what I am interpreting wrong.
// randomzie numbers
// randomize font size
// Randomzie colors
// change background when clicking
let startBtn = document.querySelector('.start-btn')
let resetBtn = document.querySelector('.reset-btn')
let timer = document.querySelector('.time__countdown')
const squares = [...document.querySelectorAll('.square')];
let gameStarted = false;
let counter = 60
startBtn.addEventListener('click', startGame)
function startGame() {
gameStarted = true;
if (gameStarted === true) {
for (let i = 0; i < squares.length; i ) {
squares[i].addEventListener('click', function() {
squares[i].style.backgroundColor = 'lightgreen'
})
}
}
randomNumber()
// This timeInterval below is not declared globally, its inside startGame() (scroll down to resetBtn.EventListener)
timeInterval = setInterval(function() {
counter--
if (counter >= 0) {
timer.innerHTML = `Time left: ${counter}`
}
}, 1000)
}
function getRandomColor() {
const letters = '0123456789ABCDEF';
let color = '#';
for (let i = 0; i < 6; i ) {
color = letters[Math.floor(Math.random() * 16)];
}
return color;
}
function randomNumber() {
for (let i = 0; i < squares.length; i ) {
const random = Math.floor(Math.random() * 25)
squares[i].textContent = random
squares[i].style.fontSize = random 15 "px";
squares[i].style.color = getRandomColor()
squares[i].style.backgroundColor = '#1F2937'
}
}
resetBtn.addEventListener('click', function() {
clearInterval(timeInterval)
counter = 60
// Why does timeInterval work here via scope when timeInterval function is inside startGame() and not declared globally??
timer.innerHTML = `Time left: 60`
})
* {
margin: 0;
padding: 0;
}
body,
html {
min-width: 100%;
min-height: 100vh;
box-sizing: border-box;
font-size: 100%;
display: flex;
justify-content: center;
align-items: center;
background-color: black;
}
img {
max-width: 100%;
display: block;
}
main {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 24%;
background-color: white;
border-radius: 10px;
}
.grid {
border: 2px solid black;
width: 100%;
display: flex;
flex-wrap: wrap;
background-color: white;
justify-content: center;
align-items: center;
gap: 2px;
padding-top: 3px;
padding-bottom: 3px;
}
.square {
border: 2px solid black;
width: 70px;
height: 70px;
display: flex;
justify-content: center;
align-items: center;
}
.time {
padding-bottom: 2em;
padding-top: 1em;
}
.btn {
margin: 1em;
}
.buttons {
display: flex;
}
<body>
<main>
<div >
<p >Time left: 60</p>
</div>
<grid >
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
</grid>
<div >
<button >Start Game</button>
<button >Reset Game</button>
</div>
</main>
<script src="index.js"></script>
</body>
CodePudding user response:
Question #1:
The variable timeInterval
was not "qualified", using var
, let
or const
.
Therefore is global. Read more on Unqualified identifier assignments
Question #2:
Have a look at how I stored the initial values for each squares with const squaresInitial
and how I used it in the resetSquares
function.
All squares are actually the same... But saving them individually allows you to have differents squares in the future. .oO( I am thinking of background images here, if I can suggest! ;) )
// randomzie numbers
// randomize font size
// Randomzie colors
// change background when clicking
let startBtn = document.querySelector('.start-btn')
let resetBtn = document.querySelector('.reset-btn')
let timer = document.querySelector('.time__countdown')
const squares = [...document.querySelectorAll('.square')];
let gameStarted = false;
let counter = 60
// Get the initial values for each squares
const squaresInitial = squares.map((square) => ({
textContent: square.textContent,
fontSize: square.style.fontSize,
color: square.style.color,
backgroundColor: square.style.backgroundColor
}))
startBtn.addEventListener('click', startGame)
// A function to call to reset alll squares with the initial values
function resetSquares() {
squares.forEach((square, index) => {
square.textContent = squaresInitial[index].textContent
square.style.fontSize = squaresInitial[index].fontSize
square.style.color = squaresInitial[index].color
square.style.backgroundColor = squaresInitial[index].backgroundColor
})
}
function startGame() {
gameStarted = true;
if (gameStarted === true) {
for (let i = 0; i < squares.length; i ) {
squares[i].addEventListener('click', function() {
squares[i].style.backgroundColor = 'lightgreen'
})
}
}
randomNumber()
// This timeInterval below is not declared globally, its inside startGame() (scroll down to resetBtn.EventListener)
timeInterval = setInterval(function() {
counter--
if (counter >= 0) {
timer.innerHTML = `Time left: ${counter}`
}
}, 1000)
}
function getRandomColor() {
const letters = '0123456789ABCDEF';
let color = '#';
for (let i = 0; i < 6; i ) {
color = letters[Math.floor(Math.random() * 16)];
}
return color;
}
function randomNumber() {
for (let i = 0; i < squares.length; i ) {
const random = Math.floor(Math.random() * 25)
squares[i].textContent = random
squares[i].style.fontSize = random 15 "px";
squares[i].style.color = getRandomColor()
squares[i].style.backgroundColor = '#1F2937'
}
}
resetBtn.addEventListener('click', function() {
clearInterval(timeInterval)
counter = 60
// Why does timeInterval work here via scope when timeInterval function is inside startGame() and not declared globally??
timer.innerHTML = `Time left: 60`
resetSquares() // Use the reset squares function here
})
* {
margin: 0;
padding: 0;
}
body,
html {
min-width: 100%;
min-height: 100vh;
box-sizing: border-box;
font-size: 100%;
display: flex;
justify-content: center;
align-items: center;
background-color: black;
}
img {
max-width: 100%;
display: block;
}
main {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 24%;
background-color: white;
border-radius: 10px;
}
.grid {
border: 2px solid black;
width: 100%;
display: flex;
flex-wrap: wrap;
background-color: white;
justify-content: center;
align-items: center;
gap: 2px;
padding-top: 3px;
padding-bottom: 3px;
}
.square {
border: 2px solid black;
width: 70px;
height: 70px;
display: flex;
justify-content: center;
align-items: center;
}
.time {
padding-bottom: 2em;
padding-top: 1em;
}
.btn {
margin: 1em;
}
.buttons {
display: flex;
}
<body>
<main>
<div >
<p >Time left: 60</p>
</div>
<grid >
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
</grid>
<div >
<button >Start Game</button>
<button >Reset Game</button>
</div>
</main>
<script src="index.js"></script>
</body>