|
| 1 | +# 29 Countdown Timer 中文指南 |
| 2 | + |
| 3 | +> 本篇作者:©[大史快跑Dashrun](https://github.com/dashrun)——Chinasoft Frontend Developer |
| 4 | +
|
| 5 | +> 简介:[JavaScript30](https://javascript30.com) 是 [Wes Bos](https://github.com/wesbos) 推出的一个 30 天挑战。项目免费提供了 30 个视频教程、30 个挑战的起始文档和 30 个挑战解决方案源代码。目的是帮助人们用纯 JavaScript 来写东西,不借助框架和库,也不使用编译器和引用。现在你看到的是这系列指南的第 29 篇。完整指南在 [GitHub](https://github.com/soyaine/JavaScript30),喜欢请 Star 哦♪(^∇^*) |
| 6 | +
|
| 7 | +> 创建时间:2017-11-6 |
| 8 | +最后更新:2017-11-12 |
| 9 | + |
| 10 | +## 挑战任务 |
| 11 | +初始文档`index-start.html`中提供了一个倒计时控制器,从`html`文档的结构可以看出,顶部的按钮可以用来增加倒计时时间,常用的时间间隔已将参数绑定在`data-time`属性上;`display`类用来显示计时的结果。 |
| 12 | +本次编程挑战的任务是通过javascript代码基于当前时间生成一个倒计时,将`结束时间`和`剩余时间`分别显示在`diaplay__time-left`类标签和`display__end-time`类标签上。 |
| 13 | + |
| 14 | +## 实现效果 |
| 15 | + |
| 16 | + |
| 17 | +## 编程思路 |
| 18 | +监听按点击事件`click`来为倒计时增加时间,使用`setInterval`函数每秒执行判断函数,若倒计时事件到,则清除当前计时器,若时间未到,则计算并刷新页面上应该显示的时间。 |
| 19 | + |
| 20 | +## 过程指南 |
| 21 | +1.定义变量及获取需要操作的DOM元素的引用。 |
| 22 | +```js |
| 23 | +const endTime = document.querySelector(".display__end-time"); |
| 24 | +const leftTime = document.querySelector(".display__time-left"); |
| 25 | +const buttons = document.querySelectorAll("button"); |
| 26 | +const date = new Date(); |
| 27 | +var left = 0;//剩余时间 |
| 28 | +var end = 0;//结束时间 |
| 29 | +var timer;//interval计时器 |
| 30 | +leftTime.innerHTML = left;//未操作时,剩余时间显示0 |
| 31 | +``` |
| 32 | +2.为button绑定点击事件,当按钮点击时执行对应的回调函数。 |
| 33 | +```js |
| 34 | +const arr = Array.from(buttons); |
| 35 | +arr.map(function(item){ |
| 36 | + item.addEventListener('click',clickAction); |
| 37 | +}); |
| 38 | +``` |
| 39 | +3.监听表单的提交事件,注意表单的调用方式。 |
| 40 | +```js |
| 41 | +document.customForm.addEventListener('submit',function(e){ |
| 42 | + e.preventDefault(); |
| 43 | + updateTime(this.minutes.value*60); |
| 44 | + updateTimer(); |
| 45 | +}); |
| 46 | +``` |
| 47 | +4.点击后的回调函数中取得点击按钮传递的秒数,调用`updateTime()`函数更新页面显示结果,并调用`updateTimer()`来更新计时器相关动作. |
| 48 | +```js |
| 49 | +function clickAction(e){ |
| 50 | + let deltaTime; |
| 51 | + deltaTime = this.dataset.time;//取得data-time属性的值 |
| 52 | + updateTime(deltaTime); |
| 53 | + |
| 54 | + //点击后更新计时器 |
| 55 | + updateTimer(); |
| 56 | +} |
| 57 | +``` |
| 58 | +5.`updateTime()`函数用来更新和页面相关的显示信息。 |
| 59 | +```js |
| 60 | + function updateTime(delta){ |
| 61 | + left = left + parseInt(delta,0); |
| 62 | + end = date.getTime() + left*1000; |
| 63 | + leftTime.innerHTML = left; |
| 64 | + endTime.innerHTML =new Date(end).toLocaleTimeString(); |
| 65 | +} |
| 66 | +``` |
| 67 | +6.`updateTimer()`函数用来执行和设定每秒检查计时器是否需要继续工作的逻辑判断。 |
| 68 | +```js |
| 69 | +function updateTimer(){ |
| 70 | + //清除以前的timer,如果不清除,新生成的定时器会和以前的定时器叠加在一起,均会生效。 |
| 71 | + if(timer){ |
| 72 | + clearInterval(timer); |
| 73 | + } |
| 74 | + |
| 75 | + // 设置新的Timer |
| 76 | + timer = setInterval(function(){ |
| 77 | + if(left == 0){ |
| 78 | + endTime.innerHTML = 'End'; |
| 79 | + clearInterval(timer); |
| 80 | + }else{ |
| 81 | + left -= 1; |
| 82 | + leftTime.innerHTML = left; |
| 83 | + } |
| 84 | +},1000); |
| 85 | +} |
| 86 | +``` |
| 87 | + |
| 88 | +## 延伸思考 |
| 89 | +本次代码中前后会定义定时器和清除定时器,另一种做法是定时器一直工作不清除,对应的按钮和表单只修改时间,不用调整定时器,当值发生变化后,下一秒定时器检测时就会开始倒计时,这样代码逻辑上会有所简化,感兴趣的朋友可以自行练习。 |
0 commit comments