简体   繁体   中英

change global variable with click event

I am trying to change a global variable with a click event and I'm stuck. I've tried it in the way the code is written below, and I'm getting the correct result in the console, but it's not working globally. How else can I do it?

 const levels = { easy: 5, medium: 3, hard: 2 } let currentLevel = levels.hard document.querySelector('#easyBtn').addEventListener('click', function () { currentLevel = levels.easy console.log (currentLevel) })
 <button id="easyBtn" type="button">Easy</button>

Full Code:

 window.addEventListener('load', init); // Globals const levels = { easy: 5, medium: 3, hard: 2 } let currentLevel = levels.hard document.querySelector('#easyBtn').addEventListener('click', function () { currentLevel = levels.easy console.log (currentLevel) }) document.querySelector('#mediumBtn').addEventListener('click', function() { currentLevel = levels.medium console.log (currentLevel) }) document.querySelector('#hardBtn').addEventListener('click', function() { currentLevel = levels.hard console.log (currentLevel) }) let time = currentLevel; let score = 0; let isPlaying; // DOM Elemennts const wordInput = document.querySelector('#word-input'); const currentWord = document.querySelector('#current-word'); const scoreDisplay = document.querySelector('#score'); const timeDisplay = document.querySelector('#time'); const message = document.querySelector('#message'); const seconds = document.querySelector('#seconds'); const words = [ 'hat', 'river', 'fun', 'billion', 'park', 'superman', 'quacky', 'juggler', 'word', 'race', 'bullet', 'computer', 'Anne', 'Jacob', 'Drew', 'garden', 'bike', 'waffle', 'hero', 'statue', 'loom', 'backpack', 'picture', 'stand', 'window', 'marker', 'bank', 'chord', 'lettuce', 'color' ]; //Initialize game function init() { seconds.innerHTML = currentLevel; //load word from array showWord(words); //start matching on word input wordInput.addEventListener('input', startMatch) //call countdown every second setInterval(countdown, 1000); //check game status setInterval(checStatus, 50); } //start match function startMatch() { if(matchWords()) { isPlaying = true; time = currentLevel + 1; showWord(words); wordInput.value = ''; score++; } //score is -1 display 0 if(score === -1) { scoreDisplay.innerHTML = 0; } else { scoreDisplay.innerHTML = score; } } //match current word to wordInput function matchWords() { if(wordInput.value === currentWord.innerHTML) { message.innerHTML = 'Correct!!!' return true; } else { message.innerHTML = ''; return false; } } function showWord(words) { // Generate random array index const randIndex = Math.floor(Math.random() * words.length); // Output random word currentWord.innerHTML = words[randIndex]; } function countdown() { //make sure time is not run out if(time > 0) { time--; }else if(time === 0) { isPaying = false; } timeDisplay.innerHTML = time; } function checStatus() { if (!isPlaying === false && time === 0) { message.innerHTML = 'Game Over!!!'; score = -1; } }
 * { margin: 0; padding: 0; box-sizing: border-box; } .body { background-color: #a8a8a8; } .header { background-color: #4646c7; display: flex; justify-content: center; height: 70px; align-items: center; } .btnSpacing { display: flex; justify-content: space-around; align-content: center; width: 100; } #easyBtn { display: flex; justify-content: center; } #mediumBtn { display: flex; justify-content: center; } #hardBtn { display: flex; justify-content: center; } #seconds { color: rgba(248, 2, 2, 0.753); font-weight: bold }
 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous"> <link rel="stylesheet" href="styles.css"> <title>Word Race</title> </head> <!DOCTYPE html> <html lang="en"> <body class="body"> <header class="header"> <h1>Word Race</h1> </header> <br> <div class="container text-center col-md-6 mx-auto "> <!-- Buttons --> <div class="btnSpacing"> <div> <button id="easyBtn" type="button" class="btn btn-success">Easy</button> </div> <div> <button id="mediumBtn" type="button" class="btn btn-warning">Medium</button> </div> <div> <button id="hardBtn" type="button" class="btn btn-danger">Hard</button> </div> </div> <br> <br> <!-- Word & Input --> <div class="row"> <div class="col-md-6 mx-auto"> <p class="lead">Type The Given Word Within <span id="seconds">5</span> Seconds:</p> <h2 class="display-2 mb-5" id="current-word">hello</h2> <input type="text" class="form-control form-control-lg" placeholder="Start typing..." id="word-input" autofocus> <h4 class="mt-3" id="message"></h4> <!-- Time & Score Columns --> <div class="row mt-5"> <div class="col-md-6"> <h3>Time Left: <span id="time">0</span> </h3> </div> <div class="col-md-6"> <h3>Score: <span id="score">0</span> </h3> </div> </div> <!-- Instructions --> <div class="row mt-5"> <div class="col-md-12"> <div class="card card-body bg-secondary text-white"> <h5>Instructions</h5> <p>Type each word in the given amount of seconds to score. To play again, just type the current word. Your score will reset.</p> </div> </div> </div> </div> </div> </div> <script src="js/main.js"></script> <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script> </body> </html>

What I take it you're asking is "Why isn't stuff like the time given updating when I update the variable?"

Javascript won't "listen" for changes on its own. After, you update the variable, you need to tell everything relying on it to also update.

There's a million different way to go about this (and a million libraries that try to make JavaScript essentially listen on changes). At the simplest level: you can try switching the currentLevel setting to a function, and have that also re-init the game.

setCurrentLevel(level) {
    currentLevel = levels.easy
    init()
    // any other stuff that needs to be updated/reset
}
// ...
document.querySelector('#easyBtn').addEventListener('click', function () {
  setCurrentLevel(levels.easy)
})

 window.addEventListener('load', init); // Globals const levels = { easy: 5, medium: 3, hard: 2 } let currentLevel = levels.hard document.querySelector('#easyBtn').addEventListener('click', function () { setCurrentLevel(levels.easy) }) document.querySelector('#mediumBtn').addEventListener('click', function() { setCurrentLevel(levels.medium) }) document.querySelector('#hardBtn').addEventListener('click', function() { setCurrentLevel(levels.hard) }) let time = currentLevel; let score = 0; let isPlaying; // DOM Elemennts const wordInput = document.querySelector('#word-input'); const currentWord = document.querySelector('#current-word'); const scoreDisplay = document.querySelector('#score'); const timeDisplay = document.querySelector('#time'); const message = document.querySelector('#message'); const seconds = document.querySelector('#seconds'); const words = [ 'hat', 'river', 'fun', 'billion', 'park', 'superman', 'quacky', 'juggler', 'word', 'race', 'bullet', 'computer', 'Anne', 'Jacob', 'Drew', 'garden', 'bike', 'waffle', 'hero', 'statue', 'loom', 'backpack', 'picture', 'stand', 'window', 'marker', 'bank', 'chord', 'lettuce', 'color' ]; //Initialize game function init() { seconds.innerHTML = currentLevel; //load word from array showWord(words); //start matching on word input wordInput.addEventListener('input', startMatch) //call countdown every second setInterval(countdown, 1000); //check game status setInterval(checStatus, 50); } //start match function startMatch() { if(matchWords()) { isPlaying = true; time = currentLevel + 1; showWord(words); wordInput.value = ''; score++; } //score is -1 display 0 if(score === -1) { scoreDisplay.innerHTML = 0; } else { scoreDisplay.innerHTML = score; } } //match current word to wordInput function matchWords() { if(wordInput.value === currentWord.innerHTML) { message.innerHTML = 'Correct!!!' return true; } else { message.innerHTML = ''; return false; } } function showWord(words) { // Generate random array index const randIndex = Math.floor(Math.random() * words.length); // Output random word currentWord.innerHTML = words[randIndex]; } function countdown() { //make sure time is not run out if(time > 0) { time--; }else if(time === 0) { isPaying = false; } timeDisplay.innerHTML = time; } function checStatus() { if (!isPlaying === false && time === 0) { message.innerHTML = 'Game Over!!!'; score = -1; } } function setCurrentLevel(level) { currentLevel = level; init(); }
 * { margin: 0; padding: 0; box-sizing: border-box; } .body { background-color: #a8a8a8; } .header { background-color: #4646c7; display: flex; justify-content: center; height: 70px; align-items: center; } .btnSpacing { display: flex; justify-content: space-around; align-content: center; width: 100; } #easyBtn { display: flex; justify-content: center; } #mediumBtn { display: flex; justify-content: center; } #hardBtn { display: flex; justify-content: center; } #seconds { color: rgba(248, 2, 2, 0.753); font-weight: bold }
 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous"> <link rel="stylesheet" href="styles.css"> <title>Word Race</title> </head> <!DOCTYPE html> <html lang="en"> <body class="body"> <header class="header"> <h1>Word Race</h1> </header> <br> <div class="container text-center col-md-6 mx-auto "> <!-- Buttons --> <div class="btnSpacing"> <div> <button id="easyBtn" type="button" class="btn btn-success">Easy</button> </div> <div> <button id="mediumBtn" type="button" class="btn btn-warning">Medium</button> </div> <div> <button id="hardBtn" type="button" class="btn btn-danger">Hard</button> </div> </div> <br> <br> <!-- Word & Input --> <div class="row"> <div class="col-md-6 mx-auto"> <p class="lead">Type The Given Word Within <span id="seconds">5</span> Seconds:</p> <h2 class="display-2 mb-5" id="current-word">hello</h2> <input type="text" class="form-control form-control-lg" placeholder="Start typing..." id="word-input" autofocus> <h4 class="mt-3" id="message"></h4> <!-- Time & Score Columns --> <div class="row mt-5"> <div class="col-md-6"> <h3>Time Left: <span id="time">0</span> </h3> </div> <div class="col-md-6"> <h3>Score: <span id="score">0</span> </h3> </div> </div> <!-- Instructions --> <div class="row mt-5"> <div class="col-md-12"> <div class="card card-body bg-secondary text-white"> <h5>Instructions</h5> <p>Type each word in the given amount of seconds to score. To play again, just type the current word. Your score will reset.</p> </div> </div> </div> </div> </div> </div> <script src="js/main.js"></script> <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script> </body> </html>


Edit: It looks like there may be some other function that may need to also be rewritten like when/how the actual countdown is set (or some general refactoring so they're called in init are there are fewer global variables) but this is the rough answer. You need to explicitly tell the game when settings have been updated and when to re-run.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM