倒计时
使用js元素写倒计时模块,当写的第一反应下是使用for循环包裹一个计算器进行计算。但是这样忽略了同步与异步直接的联系
<script>
let time = document.querySelector('.time')
let input = document.querySelector('.input')
let btn = document.querySelector('.btn')
btn.onclick=function () {
if(input.value>0) {
time.innerText = input.value
for(i=time.innerText;i>0,i--){
setTimeout(() => {
console.log(time.innerText--)// 此时time.innerText为5
},1000);
}
}else{
alert('输入正确内容')
}
}
</script>
当将计时器放进for循环后,因为setTimeout作为异步代码,会在代码执行时进入异步队列进行等待,而此时for为同步代码在持续执行循环,直到结束循环。而当for循环结束时,此时在异步队列中,已经存在n个setTimeout,此时时间一到,所有的setTimeout函数执行,time.innerText--进行n次--,输出结果为倒叙的5,4,3,2,1
虽然达到呢递减的效果,但是因为在异步队列中,所有的setTimeout函数都是在1000毫秒后的条件下触发,所以所有的数据都是在1000毫秒内执行完毕,并没有达到倒计时的效果。
这时,了解了setTimeou在for中的作用后,我们换一种方法进行
在HTML中不只有setTimeout还有setInterval,setInterval的作用是在指定的间歇时间内不断的循环内部的操作
比如
setTimeout(function(){ alert("Hello"); }, 3000);
当执行这段代码时,会不断的在3000毫秒后弹出Hello。居然能够间歇执行函数,那么是否能够解决使用setTimeout进入异步队列后一次性完成全部队列的问题。
代码如下
<script>
let time = document.querySelector('.time')
let input = document.querySelector('.input')
let btn = document.querySelector('.btn')
btn.onclick=function () {
if(input.value>0) {
time.innerText = input.value // 此时time.innerText为5
}else{
alert('输入正确数字')
}
var cle = setInterval(() => {
console.log(time.innerText--);
},1000);
}
</script>
这样,代码就会进行间隔执行,没间隔一秒钟执行一次time.innerText--,但是这是输出的值又出行了问题
setInterval会不断执行,并且不会停止,time.innerText--一直执行,成为负数依然还在--。
此时可能就会说了,我给setInterval设定条件,当time.innerText--到0时停止执行。看起来好像没问题,但是在函数中,setInterval是不会被其他条件打断的,只要执行其会一直执行下去。所以这是出现了clearInterval。
clearInterval() 方法可取消由 setInterval() 函数设定的定时执行操作。
clearInterval() 方法的参数必须是由 setInterval() 返回的 ID 值。
注意: 要使用 clearInterval() 方法, 在创建执行定时操作时要使用全局变量:
使用clearInterval完成倒计时,代码如下
</head>
<body>
<div>
<i class="time">0</i>
<input type="text" placeholder="输入整数" class="input" />
<button class="btn">开始倒计时</button>
</div>
</body>
<script>
let time = document.querySelector('.time')
let input = document.querySelector('.input')
let btn = document.querySelector('.btn')
var cle = null // 设置这个变量是为了获取setInterval的id
btn.onclick=function () {
if(input.value>0) {
time.innerText = input.value
}else{
alert('输入正确数字')
}
cle = setInterval(() => {
console.log(time.innerText--);
if(time.innerText==0){
clearInterval(cle)
}
},1000);
}
</script>