#javascript #html
#javascript #HTML
Вопрос:
Я пытаюсь создать простую игру на умножение, используя чистый Javascript. Когда я нажимаю кнопку «Пуск», она вызывает функцию TimeCalc(). Функция TimeCalc объявляет имя переменной fullTime со значением 7 и устанавливает интервал, и после каждой секунды fullTime уменьшается на 1. когда оно уменьшается до 1, оно устанавливает значение fullTime равным 7.
Если я нажимаю на кнопку «Пуск» много раз, полное время сокращается очень быстро и беспорядочно, даже если я в начале выполнил clearInterval(). Я хочу уменьшить полное время с 7 обычным способом, даже если я нажимаю на него много раз. что происходит за сценой?
Вот мой фрагмент кода. Спасибо.
const timeContainer = document.querySelector('.math__time');
const startBtn = document.querySelector('.math__start');
function timeCalc() {
clearInterval(timeLeft);
let fullTime = 7;
timeContainer.textContent = fullTime;
var timeLeft = setInterval(function() {
fullTime--;
timeContainer.textContent = fullTime;
if (fullTime === 1) {
fullTime = 7;
}
},1000);
}
startBtn.addEventListener('click', timeCalc);
*,
*:before,
*:after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.math {
background: gray;
font-family: verdana, sans-serif;
}
.math__calc {
position: absolute;
left: 50%;
top: 50%;
transform: translateY(-50%) translateX(-50%);
}
.math__num {
margin: 15px;
color: #fff;
font-size: 30px;
padding-left: 100px;
}
.math__num--wrapper {
position: relative;
}
.math__time {
padding: 10px;
background: black;
color: #fff;
position: absolute;
right: 20px;
top: 20px;
border: #fff 2px solid;
}
.math__start {
position: absolute;
left: 20px;
top: 20px;
border: 2px solid #fff;
background: #333;
color: #fff;
padding: 10px;
}
.math__multiply--symbol {
position: absolute;
bottom: -10px;
left: 10px;
font-size: 30px;
}
<!DOCTYPE html>
<html>
<head>
<title>Math</title>
<!-- default css -->
<link rel="stylesheet" type="text/css" href="css/main.css">
</head>
<body class="math">
<div class="math__time">0</div>
<button class="math__start">Start</button>
<div class="math__calc">
<div class="math__num--wrapper">
<div class="math__num math__num--one">88</div>
<span class="math__multiply--symbol">*</span>
<div class="math__num math__num--two">22</div>
</div>
<form class="math__ans">
<input type="text" name="answer" class="math__ans--user">
</form>
</div>
</body>
</html>
Ответ №1:
Вам нужно объявить timeLeft
в глобальной области видимости и изменить ее внутри функции
const timeContainer = document.querySelector('.math__time');
const startBtn = document.querySelector('.math__start');
let timeLeft;
let fullTime;
function timeCalc() {
clearInterval(timeLeft);
fullTime = 7;
timeContainer.textContent = fullTime;
timeLeft = setInterval(function() {
fullTime--;
timeContainer.textContent = fullTime;
if (fullTime === 1) {
fullTime = 8
}
},1000);
}
startBtn.addEventListener('click', timeCalc);
*,
*:before,
*:after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.math {
background: gray;
font-family: verdana, sans-serif;
}
.math__calc {
position: absolute;
left: 50%;
top: 50%;
transform: translateY(-50%) translateX(-50%);
}
.math__num {
margin: 15px;
color: #fff;
font-size: 30px;
padding-left: 100px;
}
.math__num--wrapper {
position: relative;
}
.math__time {
padding: 10px;
background: black;
color: #fff;
position: absolute;
right: 20px;
top: 20px;
border: #fff 2px solid;
}
.math__start {
position: absolute;
left: 20px;
top: 20px;
border: 2px solid #fff;
background: #333;
color: #fff;
padding: 10px;
}
.math__multiply--symbol {
position: absolute;
bottom: -10px;
left: 10px;
font-size: 30px;
}
<!DOCTYPE html>
<html>
<head>
<title>Math</title>
<!-- default css -->
<link rel="stylesheet" type="text/css" href="css/main.css">
</head>
<body class="math">
<div class="math__time">0</div>
<button class="math__start">Start</button>
<div class="math__calc">
<div class="math__num--wrapper">
<div class="math__num math__num--one">88</div>
<span class="math__multiply--symbol">*</span>
<div class="math__num math__num--two">22</div>
</div>
<form class="math__ans">
<input type="text" name="answer" class="math__ans--user">
</form>
</div>
</body>
</html>
Ответ №2:
Махир прав, единственным дополнением было бы не загрязнять ваше глобальное пространство. Создайте замыкание для хранения этих переменных. Я обновил функцию, чтобы возвращать функцию.
Проблема
Ваш clearInterval(timeLeft)
на самом деле ничего не очищает. timeLeft
Не определено на момент очистки.
Решение
Перемещение вашего timeleft
выполняется в более широком масштабе. Вы можете либо: — Поместить его в глобальное пространство имен (не рекомендуется) — Создать область видимости вокруг функции TimeCalc.
Я реализовал второе решение, приведенное ниже. Сначала я изменил timeCalc()
. Теперь timeCalc()
создает функцию. Эта функция может использоваться в качестве обратного вызова для .addEventListener()
.
Затем вызов этой функции в .addEventListener()
вернет функцию таймера с переменными, заключенными в замыкание. Я также изменил fulltime
в функции на 8, чтобы показывать 7 секунд после того, как обратный отсчет достиг 1.
const timeContainer = document.querySelector('.math__time');
const startBtn = document.querySelector('.math__start');
function timeCalc() {
let timeLeft = null;
let fullTime = 7;
return function() {
clearInterval(timeLeft);
fullTime = 7;
timeContainer.textContent = fullTime;
timeLeft = setInterval(function() {
fullTime--;
timeContainer.textContent = fullTime;
if (fullTime === 1) {
fullTime = 8;
}
},1000);
}
}
startBtn.addEventListener('click', timeCalc());
*,
*:before,
*:after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.math {
background: gray;
font-family: verdana, sans-serif;
}
.math__calc {
position: absolute;
left: 50%;
top: 50%;
transform: translateY(-50%) translateX(-50%);
}
.math__num {
margin: 15px;
color: #fff;
font-size: 30px;
padding-left: 100px;
}
.math__num--wrapper {
position: relative;
}
.math__time {
padding: 10px;
background: black;
color: #fff;
position: absolute;
right: 20px;
top: 20px;
border: #fff 2px solid;
}
.math__start {
position: absolute;
left: 20px;
top: 20px;
border: 2px solid #fff;
background: #333;
color: #fff;
padding: 10px;
}
.math__multiply--symbol {
position: absolute;
bottom: -10px;
left: 10px;
font-size: 30px;
}
<!DOCTYPE html>
<html>
<head>
<title>Math</title>
<!-- default css -->
<link rel="stylesheet" type="text/css" href="css/main.css">
</head>
<body class="math">
<div class="math__time">0</div>
<button class="math__start">Start</button>
<div class="math__calc">
<div class="math__num--wrapper">
<div class="math__num math__num--one">88</div>
<span class="math__multiply--symbol">*</span>
<div class="math__num math__num--two">22</div>
</div>
<form class="math__ans">
<input type="text" name="answer" class="math__ans--user">
</form>
</div>
</body>
</html>
Комментарии:
1. Что происходило внутри функции TimeCalc () до того, как она была решена? почему возникла эта проблема? И теперь, почему нам нужно добавлять скобки в .addEventListener во время вызова функции?