前言有时,您将需要构建一个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>推荐JavaScript经典实例学习资料文章《图文细说JavaScript 的运行机制》《一个轻量级 JavaScript 全文搜索库,轻松实现站内离线搜索》《推荐Web程序员常用的15个源代码编辑器》《10个实用的JS技巧「值得收藏」》《细品269个JavaScript小函数,让你少加班熬夜(一)「值得收藏」》《细品269个JavaScript小函数,让你少加班熬夜(二)「值得收藏」》《细品269个JavaScript小函数,让你少加班熬夜(三)「值得收藏」》《细品269个JavaScript小函数,让你少加班熬夜(四)「值得收藏」》《细品269个JavaScript小函数,让你少加班熬夜(五)「值得收藏」》《细品269个JavaScript小函数,让你少加班熬夜(六)「值得收藏」》《深入JavaScript教你内存泄漏如何防范》《手把手教你7个有趣的JavaScript 项目-上「附源码」》《手把手教你7个有趣的JavaScript 项目-下「附源码」》《JavaScript 使用 mediaDevices API 访问摄像头自拍》《手把手教你前端代码如何做错误上报「JS篇」》《一文让你彻底搞懂移动前端和Web 前端区别在哪里》《63个JavaScript 正则大礼包「值得收藏」》《提高你的 JavaScript 技能10 个问答题》《JavaScript图表库的5个首选》《一文彻底搞懂JavaScript 中Object.freeze与Object.seal的用法》《可视化的 JS:动态图演示 – 事件循环 Event Loop的过程》《教你如何用动态规划和贪心算法实现前端瀑布流布局「实践」》《可视化的 js:动态图演示 Promises & Async/Await 的过程》《原生JS封装拖动验证滑块你会吗?「实践」》《如何实现高性能的在线 PDF 预览》《细说使用字体库加密数据-仿58同城》《Node.js要完了吗?》《Pug 3.0.0正式发布,不再支持 Node.js 6/8》《纯JS手写轮播图(代码逻辑清晰,通俗易懂)》《JavaScript 20 年 中文版之创立标准》《值得收藏的前端常用60余种工具方法「JS篇」》《箭头函数和常规函数之间的 5 个区别》《通过发布/订阅的设计模式搞懂 Node.js 核心模块 Events》《「前端篇」不再为正则烦恼》《「速围」Node.js V14.3.0 发布支持顶级 Await 和 REPL 增强功能》《深入细品浏览器原理「流程图」》《JavaScript 已进入第三个时代,未来将何去何从?》《前端上传前预览文件 image、text、json、video、audio「实践」》《深入细品 EventLoop 和浏览器渲染、帧动画、空闲回调的关系》《推荐13个有用的JavaScript数组技巧「值得收藏」》《前端必备基础知识:window.location 详解》《不要再依赖CommonJS了》《犀牛书作者:最该忘记的JavaScript特性》《36个工作中常用的JavaScript函数片段「值得收藏」》《Node + H5 实现大文件分片上传、断点续传》《一文了解文件上传全过程(1.8w字深度解析)「前端进阶必备」》《【实践总结】关于小程序挣脱枷锁实现批量上传》《手把手教你前端的各种文件上传攻略和大文件断点续传》《字节跳动面试官:请你实现一个大文件上传和断点续传》《谈谈前端关于文件上传下载那些事【实践】》《手把手教你如何编写一个前端图片压缩、方向纠正、预览、上传插件》《最全的 JavaScript 模块化方案和工具》《「前端进阶」JS中的内存管理》《JavaScript正则深入以及10个非常有意思的正则实战》《前端面试者经常忽视的一道JavaScript 面试题》《一行JS代码实现一个简单的模板字符串替换「实践」》《JS代码是如何被压缩的「前端高级进阶」》《前端开发规范:命名规范、html规范、css规范、js规范》《【规范篇】前端团队代码规范最佳实践》《100个原生JavaScript代码片段知识点详细汇总【实践】》《关于前端174道 JavaScript知识点汇总(一)》《关于前端174道 JavaScript知识点汇总(二)》《关于前端174道 JavaScript知识点汇总(三)》《几个非常有意思的javascript知识点总结【实践】》《都2020年了,你还不会JavaScript 装饰器?》《JavaScript实现图片合成下载》《70个JavaScript知识点详细总结(上)【实践】》《70个JavaScript知识点详细总结(下)【实践】》《开源了一个 JavaScript 版敏感词过滤库》《送你 43 道 JavaScript 面试题》《3个很棒的小众JavaScript库,你值得拥有》《手把手教你深入巩固JavaScript知识体系【思维导图】》《推荐7个很棒的JavaScript产品步骤引导库》《Echa哥教你彻底弄懂 JavaScript 执行机制》《一个合格的中级前端工程师需要掌握的 28 个 JavaScript 技巧》《深入解析高频项目中运用到的知识点汇总【JS篇】》《JavaScript 工具函数大全【新】》《从JavaScript中看设计模式(总结)》《身份证号码的正则表达式及验证详解(JavaScript,Regex)》《浏览器中实现JavaScript计时器的4种创新方式》《Three.js 动效方案》《手把手教你常用的59个JS类方法》《127个常用的JS代码片段,每段代码花30秒就能看懂-【上】》《深入浅出讲解 js 深拷贝 vs 浅拷贝》《手把手教你JS开发H5游戏【消灭星星】》《深入浅出讲解JS中this/apply/call/bind巧妙用法【实践】》《手把手教你全方位解读JS中this真正含义【实践】》《书到用时方恨少,一大波JS开发工具函数来了》《干货满满!如何优雅简洁地实现时钟翻牌器(支持JS/Vue/React)》《手把手教你JS 异步编程六种方案【实践】》《让你减少加班的15条高效JS技巧知识点汇总【实践】》《手把手教你JS开发H5游戏【黄金矿工】》《手把手教你JS实现监控浏览器上下左右滚动》《JS 经典实例知识点整理汇总【实践】》《2.6万字JS干货分享,带你领略前端魅力【基础篇】》《2.6万字JS干货分享,带你领略前端魅力【实践篇】》《简单几步让你的 JS 写得更漂亮》《恭喜你获得治疗JS this的详细药方》《谈谈前端关于文件上传下载那些事【实践】》《面试中教你绕过关于 JavaScript 作用域的 5 个坑》《Jquery插件(常用的插件库)》《【JS】如何防止重复发送ajax请求》《JavaScript+Canvas实现自定义画板》《Continuation 在 JS 中的应用「前端篇」》
本文出自快速备案,转载时请注明出处及相应链接。