首页 > 解决方案 > 使用点击事件更改全局变量

问题描述

我正在尝试使用单击事件更改全局变量,但我被卡住了。我已经按照下面编写代码的方式进行了尝试,并且在控制台中得到了正确的结果,但它不能在全局范围内工作。我还能怎么做?

    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>

完整代码:

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>

标签: javascriptglobal-variablesaddeventlistenermouseclick-event

解决方案


我认为您要问的是“为什么在我更新变量时没有更新时间之类的东西?”

Javascript 不会自行“监听”更改。更新变量之后,您需要告诉依赖它的所有内容也进行更新。

有一百万种不同的方法可以解决这个问题(以及一百万个试图JavaScript 从本质上监听变化的库)。在最简单的级别:您可以尝试将 currentLevel 设置切换为一个函数,并让它重新启动游戏。

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>


编辑:看起来可能还需要重写一些其他函数,例如何时/如何设置实际倒计时(或一些一般性重构,因此在初始化时调用它们,全局变量较少),但这是粗略的回答。您需要明确告诉游戏设置何时更新以及何时重新运行。


推荐阅读