我正在尝试使用纯Javascript构建简单的乘法游戏。当我单击开始按钮时,它将调用函数timeCalc()。 timeCalc函数声明变量名称fullTime,其值为7,并设置间隔,每隔一秒钟将fullTime减小1。当其减小为1时,将fullTime值设置为7。
如果我多次单击“开始”按钮,即使我一开始就做过clearInterval(),fullTime也会如此快速且无序地递减。我想以正常方式将fullTime从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>
答案 0 :(得分:2)
您需要在全局范围内声明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>
答案 1 :(得分:0)
Maheer是正确的,唯一的补充就是不会污染您的全球空间。创建一个闭合来保存这些变量。我更新了函数以返回一个函数。
问题
您的clearInterval(timeLeft)
实际上没有清除任何内容。 timeLeft
在清除时未定义。
解决方案
移动timeleft
的范围更大。您可以:
-将其放在全局名称空间中(不推荐)
-在timeCalc函数周围创建一个作用域。
我实现了下面的第二个解决方案。我首先更改了timeCalc()
。现在timeCalc()
产生一个函数。此函数可用作.addEventListener()
的回调。
然后在.addEventListener()
中调用该函数将返回一个计时器函数,其变量包含在闭包中。我还将函数中的fulltime
更改为8,以显示倒数到1后的7秒。
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>