仅用18行JavaScript实现一个倒数计时器(用javascript怎么写一分钟倒计时)
xiyangw 2022-12-06 10:04 31 浏览 0 评论
前言
有时,您将需要构建一个JavaScript倒数时钟。您可能有活动,销售,促销或游戏。您可以使用原始JavaScript构建时钟,而不用寻找最近的插件。虽然有很多很棒的时钟插件,但是使用原始JavaScript可以带来以下好处:
您的代码将是轻量级的,因为它将具有零依赖性。
您的网站将表现更好。您无需加载外部脚本和样式表。
您将拥有更多控制权。您将构建时钟,使其行为完全符合您希望的方式(而不是尝试将插件弯曲到您的意愿)。
因此,事不宜迟,这里介绍了如何仅用18行JavaScript来制作自己的倒计时时钟

基本时钟:倒数到特定的日期或时间
以下是创建基本时钟所涉及步骤的快速概述:
设置有效的结束日期。
计算剩余时间。
将时间转换为可用格式。
将时钟数据输出为可重复使用的对象。
在页面上显示时钟,并在时钟为零时停止时钟。
设定有效的结束日期
首先,您需要设置一个有效的结束日期。这应该是JavaScript的Date.parse()方法可以理解的任何格式的字符串。例如:
在ISO 8601格式:
const deadline = '2015-12-31';
简短格式:
const deadline = '31/12/2015';
或者,长格式:
const deadline = 'December 31 2015';
这些格式中的每一种都允许您指定确切的时间和时区(对于ISO日期,则为UTC的偏移量)。例如:
const deadline = 'December 31 2015 23:59:59 GMT+0200';
您可以在本文中阅读有关JavaScript中日期格式的更多信息。
计算剩余时间
下一步是计算剩余时间。我们需要编写一个函数,该函数需要一个表示给定结束时间的字符串(如上所述)。然后,我们计算该时间与当前时间之间的时差。看起来像这样:
function getTimeRemaining(endtime){ const total = Date.parse(endtime) - Date.parse(new Date()); const seconds = Math.floor( (total/1000) % 60 ); const minutes = Math.floor( (total/1000/60) % 60 ); const hours = Math.floor( (total/(1000*60*60)) % 24 ); const days = Math.floor( total/(1000*60*60*24) ); return { total, days, hours, minutes, seconds }; }
首先,我们创建一个变量total,以保留剩余时间直到截止日期。该Date.parse()函数将时间字符串转换为毫秒值。这使我们可以相减两次,并获得两者之间的时间量。
const total = Date.parse(endtime) - Date.parse(new Date());
将时间转换为可用格式
现在,我们要将毫秒转换为天,小时,分钟和秒。让我们以秒为例:
const seconds = Math.floor( (t/1000) % 60 );
让我们分解一下这里发生的事情。
将毫秒除以1000可转换为秒: (t/1000)
将总秒数除以60,然后取余数。您不希望所有的秒数,仅需要计算分钟数之后剩下的秒数:(t/1000) % 60
四舍五入到最接近的整数。这是因为您需要完整的秒数,而不是几分之一秒:Math.floor( (t/1000) % 60 )
重复此逻辑,将毫秒转换为分钟,小时和天。
输出时钟数据作为可重用对象
准备好几天,几小时,几分钟和几秒钟之后,我们现在可以将数据作为可重用的对象返回:
return { total, days, hours, minutes, seconds };
该对象允许您调用函数并获取任何计算值。这是如何获取剩余时间的示例:
getTimeRemaining(deadline).minutes
方便吧?
显示时钟并在达到零时停止
现在,我们有了一个可以花费剩余的天,小时,分钟和秒的功能,我们可以构建时钟了。首先,我们将创建以下HTML元素来保存时钟:
<div id="clockdiv"></div>
然后,我们将编写一个在新div中输出时钟数据的函数:
function initializeClock(id, endtime) { const clock = document.getElementById(id); const timeinterval = setInterval(() => { const t = getTimeRemaining(endtime); clock.innerHTML = 'days: ' + t.days + '<br>' + 'hours: '+ t.hours + '<br>' + 'minutes: ' + t.minutes + '<br>' + 'seconds: ' + t.seconds; if (t.total <= 0) { clearInterval(timeinterval); } },1000); }
该函数有两个参数。这些是包含我们时钟的元素的ID,以及倒计时的结束时间。在函数内部,我们将声明一个clock变量并将其用于存储对我们的时钟容器div的引用。这意味着我们不必继续查询DOM。
接下来,我们将使用setInterval每秒执行一个匿名函数。此功能将执行以下操作:
计算剩余时间。
将剩余时间输出到我们的div。
如果剩余时间为零,请停止计时。
此时,剩下的唯一步骤是像这样运行时钟:
initializeClock('clockdiv', deadline);
恭喜你!现在,您仅用18行JavaScript就拥有了一个基本时钟。
准备显示时钟
在设置时钟样式之前,我们需要进行一些细化。
消除初始延迟,使您的时钟立即显示。
提高时钟脚本的效率,以免持续重建整个时钟。
根据需要添加前导零。
消除初始延迟
在时钟中,我们习惯于setInterval每秒更新一次显示。多数情况下,这很好,除非在开始时会有一秒钟的延迟。要消除此延迟,我们必须在间隔开始之前更新一次时钟。
让我们将要传递给setInterval它的匿名函数移到其自己的独立函数中。我们可以命名这个函数updateClock。在updateClock外部调用该函数setInterval,然后在内部再次调用setInterval。这样,时钟显示就没有延迟了。
在您的JavaScript中,替换为:
const timeinterval = setInterval(() => { ... },1000);
有了这个:
function updateClock(){ const t = getTimeRemaining(endtime); clock.innerHTML = 'days: ' + t.days + '<br>' + 'hours: '+ t.hours + '<br>' + 'minutes: ' + t.minutes + '<br>' + 'seconds: ' + t.seconds; if (t.total <= 0) { clearInterval(timeinterval); } } updateClock(); // run function once at first to avoid delay var timeinterval = setInterval(updateClock,1000);
避免持续重建时钟
我们需要使时钟脚本更高效。我们只想更新时钟中的数字,而不是每秒重新构建整个时钟。实现此目的的一种方法是将每个数字放在span标签中,然后仅更新这些跨度的内容。
这是HTML:
<div id="clockdiv"> Days: <span class="days"></span><br> Hours: <span class="hours"></span><br> Minutes: <span class="minutes"></span><br> Seconds: <span class="seconds"></span> </div>
现在让我们参考这些元素。在clock定义变量的位置之后添加以下代码
const daysSpan = clock.querySelector('.days'); const hoursSpan = clock.querySelector('.hours'); const minutesSpan = clock.querySelector('.minutes'); const secondsSpan = clock.querySelector('.seconds');
接下来,我们需要更改updateClock功能以及更新数字。新代码如下所示:
function updateClock(){ const t = getTimeRemaining(endtime); daysSpan.innerHTML = t.days; hoursSpan.innerHTML = t.hours; minutesSpan.innerHTML = t.minutes; secondsSpan.innerHTML = t.seconds; ... }
添加前导零
现在时钟不再每秒都在重建,我们还有另一件事要做:添加前导零。例如,不是让时钟显示7秒,而是显示07秒。一种简单的方法是在数字的开头添加字符串“ 0”,然后切掉最后两位数字。
例如,要在“ seconds”值上添加前导零,您可以对此进行更改:
secondsSpan.innerHTML = t.seconds;
对此:
secondsSpan.innerHTML = ('0' + t.seconds).slice(-2);
如果需要,您也可以在分钟和小时中添加前导零。如果您走了这么远,恭喜!您的时钟现在可以显示了。
注意:您可能需要在CodePen中单击“重新运行”才能开始倒计时。
更进一步
下面的示例演示如何针对某些用例扩展时钟。它们都是基于上面看到的基本示例。
自动安排时钟
假设我们希望时钟显示在某些日子,而不是其他日子。例如,我们可能会发生一系列事件,并且不想每次都手动更新时钟。这是提前安排事情的方法。
通过在CSS中将其display属性设置为隐藏时钟none。然后将以下内容添加到initializeClock函数中(以开头的行之后var clock)。一旦initializeClock调用此函数,这将导致时钟仅显示:
clock.style.display = 'block';
接下来,我们可以指定显示时钟的日期。这将替换deadline变量:
const schedule = [ ['Jul 25 2015', 'Sept 20 2015'], ['Sept 21 2015', 'Jul 25 2016'], ['Jul 25 2016', 'Jul 25 2030'] ];
schedule数组中的每个元素代表一个开始日期和一个结束日期。如上所述,可以包括时间和时区,但是我在这里使用了简单的日期来保持代码的可读性。
最后,当用户加载页面时,我们需要检查是否在指定的时间范围内。该代码应替换先前对该initializeClock函数的调用。
// iterate over each element in the schedule for (var i=0; i<schedule.length; i++) { var startDate = schedule[i][0]; var endDate = schedule[i][1]; // put dates in milliseconds for easy comparisons var startMs = Date.parse(startDate); var endMs = Date.parse(endDate); var currentMs = Date.parse(new Date()); // if current date is between start and end dates, display clock if (endMs > currentMs && currentMs >= startMs ) { initializeClock('clockdiv', endDate); } } schedule.forEach(([startDate, endDate]) => { // put dates in milliseconds for easy comparisons const startMs = Date.parse(startDate); const endMs = Date.parse(endDate); const currentMs = Date.parse(new Date()); // if current date is between start and end dates, display clock if (endMs > currentMs && currentMs >= startMs ) { initializeClock('clockdiv', endDate); } });
现在,您可以提前安排时钟,而无需手动更新。您可以根据需要缩短代码。为了便于阅读,我让我变得冗长。
从用户到达起将计时器设置为10分钟
用户到达或开始特定任务后,有必要在给定的时间内设置倒计时。我们将在此处将计时器设置为10分钟,但是您可以使用任意时间。
我们需要做的就是deadline用这个替换变量:
const timeInMinutes = 10; const currentTime = Date.parse(new Date()); const deadline = new Date(currentTime + timeInMinutes*60*1000);
该代码将花费当前时间,并增加十分钟。这些值将转换为毫秒,因此可以将它们加在一起并变成新的截止日期。
现在,我们有了一个时钟,可以从用户到达时开始倒数十分钟。随意玩耍,尝试不同的时间长度。
跨页面保持时钟进度
有时,有必要将时钟状态保留的时间不仅限于当前页面。如果我们想在整个网站上设置10分钟的计时器,则我们不希望在用户转到其他页面时将其重置。
一种解决方案是将时钟的结束时间保存在cookie中。这样,导航到新页面不会将结束时间重置为现在的十分钟。
这是逻辑:
如果Cookie中记录了截止日期,请使用该截止日期。
如果不存在该cookie,则设置一个新的截止日期并将其存储在cookie中。
要实现这一点,请用deadline以下内容替换变量:
let deadline; // if there's a cookie with the name myClock, use that value as the deadline if(document.cookie && document.cookie.match('myClock')){ // get deadline value from cookie deadline = document.cookie.match(/(^|;)myClock=([^;]+)/)[2]; } else { // otherwise, set a deadline 10 minutes from now and // save it in a cookie with that name // create deadline 10 minutes from now const timeInMinutes = 10; const currentTime = Date.parse(new Date()); deadline = new Date(currentTime + timeInMinutes*60*1000); // store deadline in cookie for future reference document.cookie = 'myClock=' + deadline + '; path=/; domain=.yourdomain.com'; }
这段代码利用了cookie和正则表达式,它们本身就是单独的主题。因此,我在这里不再赘述。需要注意的一件事是,您需要更改.yourdomain.com为实际域。
有关客户端事件的重要警告
JavaScript日期和时间是从用户计算机中获取的。这意味着用户可以通过更改计算机上的时间来影响JavaScript时钟。在大多数情况下,这无关紧要。但是,在某些超级敏感的情况下,有必要从服务器获取时间。可以使用一些PHP或Ajax来完成,这两者都超出了本教程的范围。
从服务器获取时间后,我们可以使用本教程中的相同技术来使用它。
加起来
阅读完本文中的示例之后,您现在知道如何仅用几行原始JavaScript代码创建自己的倒数计时器!我们已经研究了如何制作基本的倒数时钟并有效显示它。我们还介绍了添加一些有用的附加功能,包括计划,绝对时间和相对时间,以及使用Cookie保留页面和站点访问之间的状态。
完整代码
<!DOCTYPE html> <html lang="zh"> <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" /> <title>Countdown Clock</title> <style type="text/css"> body{ text-align: center; background: #00ECB9; font-family: sans-serif; font-weight: 100; } h1{ color: #396; font-weight: 100; font-size: 40px; margin: 40px 0px 20px; } #clockdiv{ font-family: sans-serif; color: #fff; display: inline-block; font-weight: 100; text-align: center; font-size: 30px; } #clockdiv > div{ padding: 10px; border-radius: 3px; background: #00BF96; display: inline-block; } #clockdiv div > span{ padding: 15px; border-radius: 3px; background: #00816A; display: inline-block; } .smalltext{ padding-top: 5px; font-size: 16px; } </style> </head> <body> <h1>Countdown Clock</h1> <div id="clockdiv"> <div> <span class="days"></span> <div class="smalltext">Days</div> </div> <div> <span class="hours"></span> <div class="smalltext">Hours</div> </div> <div> <span class="minutes"></span> <div class="smalltext">Minutes</div> </div> <div> <span class="seconds"></span> <div class="smalltext">Seconds</div> </div> </div> <script type="text/javascript"> function getTimeRemaining(endtime) { const total = Date.parse(endtime) - Date.parse(new Date()); const seconds = Math.floor((total / 1000) % 60); const minutes = Math.floor((total / 1000 / 60) % 60); const hours = Math.floor((total / (1000 * 60 * 60)) % 24); const days = Math.floor(total / (1000 * 60 * 60 * 24)); return { total, days, hours, minutes, seconds }; } function initializeClock(id, endtime) { const clock = document.getElementById(id); const daysSpan = clock.querySelector('.days'); const hoursSpan = clock.querySelector('.hours'); const minutesSpan = clock.querySelector('.minutes'); const secondsSpan = clock.querySelector('.seconds'); function updateClock() { const t = getTimeRemaining(endtime); daysSpan.innerHTML = t.days; hoursSpan.innerHTML = ('0' + t.hours).slice(-2); minutesSpan.innerHTML = ('0' + t.minutes).slice(-2); secondsSpan.innerHTML = ('0' + t.seconds).slice(-2); if (t.total <= 0) { clearInterval(timeinterval); } } updateClock(); const timeinterval = setInterval(updateClock, 1000); } const deadline = new Date(Date.parse(new Date()) + 15 * 24 * 60 * 60 * 1000); initializeClock('clockdiv', deadline); </script> </body> </html>
相关推荐
- spring利用spring.handlers解析自定义配置(spring validation 自定义)
-
一、问题我们在spring的xml配置文件里经常定义各种各样的配置(tx、bean、mvc、bean等等)。以及集成第三方框架时,也会看到一些spring之外的配置,例如dubbo的配置、securi...
- 「Spring源码分析」AOP源码解析(上篇)(spring源码深度解析(第2版))
-
前言前面写了六篇文章详细地分析了SpringBean加载流程,这部分完了之后就要进入一个比较困难的部分了,就是AOP的实现原理分析。为了探究AOP实现原理,首先定义几个类,一个Dao接口:1&nbs...
-
- Spring 解析注册BeanDefinition这一篇就Over
-
一、简介:学习过Spring框架的人一定都会听过Spring的IoC(控制反转)、DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC、...
-
2023-03-20 14:53 xiyangw
- 域、模块、空间、闭包,你真的懂了吗?(模块控制域与作用域的关系)
-
Javascript有一个特性叫做域。尽管对于初学者来说理解域是有难度的,但我会尽力用最简单的方式让你理解域。理解域能让你的代码更优秀,减少错误,及有助于你做出更强大的模式设计。什么是域域是在运行时,...
-
- 这一次搞懂Spring自定义标签以及注解解析原理
-
前言在上一篇文章中分析了Spring是如何解析默认标签的,并封装为BeanDefinition注册到缓存中,这一篇就来看看对于像context这种自定义标签是如...
-
2023-03-20 14:53 xiyangw
-
- 前端基础进阶(七)-前端工程师最容易出错的问题-this关键字
-
我们在学习JavaScript的时候,因为对一些概念不是很清楚,但是又会通过一些简洁的方式把它给记下来,那么这样自己记下来的概念和真正的概念产生了很强的偏差.当...
-
2023-03-20 14:52 xiyangw
-
- 深入K8s:守护进程DaemonSet及其源码分析(k8s 进程)
-
建议学习:膜拜!阿里内部都在强推的K8S(kubernetes)学习指南,不能再详细了最近也一直在加班,处理项目中的事情,发现问题越多越是感觉自己的能力不足,...
-
2023-03-20 14:52 xiyangw
-
- Spring 是如何解析 bean 标签的?(spring beans标签)
-
前情回顾上回「SpringIoC容器初始化(2)」说到了Spring如何解析我们定义的<bean>标签,代码跟进了一层又一层,跋山涉水,...
-
2023-03-20 14:52 xiyangw
-
- 快速了解JavaScript文本框操作(javascript文本框代码)
-
HTML中使用<input>元素表示单行输入框和<textarea>元素表示多行文本框。HTML中使用的<input&...
-
2023-03-20 14:51 xiyangw
-
- 荐读|30道JavaOOP面试题,可以和面试官扯皮了
-
面试是我们每个人都要经历的事情,大部分人且不止一次,今天给大家准备了30道JavaOOP面试题,希望能够帮助到对Java感兴趣的同学,让大家在找工作的时候能够...
-
2023-03-20 14:51 xiyangw
-
- 源码系列——mybatis源码刨析总结,下(mybatis源码分析)
-
接上文简答题一.1.Mybatis动态sql是做什么的?1.动态sql就是根据条件标签动态的拼接sql,包括判空,循环,拼接等2.哪些动态sql?动态sql大...
-
2023-03-20 14:50 xiyangw
-
- Java面试题(第二弹)(java面试题及答案整理)
-
1.抽象类和接口的区别?接口可以被多重implements,抽象类只能被单一extends接口只有定义,抽象类可以有定义和实现接口的字段定义默认为:public...
-
2023-03-20 14:50 xiyangw
-
- mybatis3 源码深度解析-动态 sql 实现原理(sql数据库基础知识)
-
大纲动态sql使用示例SqlSource和BoundSql以及实现类LanguageDriver以及实现类SqlNode以及实现类动态sql解...
-
2023-03-20 14:50 xiyangw
-
- 第43节 Text、Comment及CDATASection(第43节 Text、Comment及CDATASection)
-
本内容是《Web前端开发之Javascript视频》的课件,请配合大师哥《Javascript》视频课程学习。文本节点用Text类型表示,包含的是可以按字面解释...
-
2023-03-20 14:49 xiyangw
- Qt读写三种文件(qt读取文件数据并赋值给变量)
-
第一种INI配置文件.ini文件是InitializationFile的缩写,即初始化文件。除了windows现在很多其他操作系统下面的应用软件也有.ini文件,用来配置应用软件以实现不同用户的要...
你 发表评论:
欢迎- 一周热门
-
-
第十四天 JSON和Python(封禁在禽兽家的第十四天小说)
-
asp.net core supersocket介绍以及源码分析(asp.net core oauth2.0)
-
Java19的新特性(java19和17的区别)
-
08《Nginx 入门教程》Nginx 的 Http 模块介绍(中)
-
笔记本无线连接局域网的设置教程(笔记本无线连接局域网的设置教程在哪)
-
Linux下HTTP服务配置教程(java安装教程及环境配置方法)
-
SEO基础教程(一):适合新手的SEO教程(seo秘籍-自学seo零基础知识入门优化教程)
-
SpringCache,统一Redis、Memcached操作,轻松将缓存与业务解耦
-
web前端基础入门教程(非常详细)HTML+CSS+JavaScript
-
使用nodejs和express搭建http web服务(nodejs搭建服务器)
-
- 标签列表
-
- XSLT (103)
- Java Number & (81)
- Math 类 (81)
- Java String类 (82)
- Java9新特性 (82)
- C语言enum(枚举) (81)
- C语言输入& (89)
- 输出 (89)
- C语言标准库- (303)
- Go 语言基础语法 (80)
- Go 语言变量 (79)
- Go 语言函数 (80)
- PHP 变量 (82)
- flashtext (111)
- c#正则 (120)
- jquery版本 (110)
- js去掉字符串中的某个字符 (119)
- vue过滤 (132)
- c#ocr (93)
- javascript字符串转数字 (81)
- ASP Session (95)
- ASP Response (86)
- JavaScript 函数定义 (84)
- JavaScript 闭包 (90)
- JS 类 (83)