本文出自:春哥个人博客:http://www.liyuechun.org
作者:©黎跃春-追时间的人
简介:JavaScript30 是 Wes Bos 推出的一个 30 天挑战。项目免费提供了 30 个视频教程、30 个挑战的起始文档和 30 个挑战解决方案源代码。目的是帮助人们用纯 JavaScript 来写东西,不借助框架和库,也不使用编译器和引用。现在你看到的是这系列指南的第 29 篇。完整中文版指南及视频教程在 从零到壹全栈部落。

效果图

在线效果

第20天的挑战是,设置一个倒计时时间,接下来开始倒计时。

HTML代码

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title>Countdown Timer</title><link href='https://fonts.googleapis.com/css?family=Inconsolata' rel='stylesheet' type='text/css'><link rel="stylesheet" href="style.css">
</head><body><div class="timer"><div class="timer__controls"><button data-time="20" class="timer__button">20 Secs</button><button data-time="300" class="timer__button">Work 5</button><button data-time="900" class="timer__button">Quick 15</button><button data-time="1200" class="timer__button">Snack 20</button><button data-time="3600" class="timer__button">Lunch Break</button><form name="customForm" id="custom"><input type="text" name="minutes" placeholder="Enter Minutes"></form></div><div class="display"><h1 class="display__time-left"></h1><p class="display__end-time"></p></div></div>
</body>
</html>
  • 上面的button中自定义的data-time为倒计时时间,以秒为单位。
  • form为自定义倒计时时间,以分为单位。
  • class为display__time-left的div主要为了展示倒计时的动态。
  • class为display__end-time的div主要为了展示倒计时什么时候结束。

CSS 代码

html {box-sizing: border-box;font-size: 10px;background: #8E24AA;background: linear-gradient(45deg, #42a5f5 0%, #478ed1 50%, #0d47a1 100%);
}*,
*:before,
*:after {box-sizing: inherit;
}body {margin: 0;text-align: center;font-family: 'Inconsolata', monospace;
}.display__time-left {font-weight: 100;font-size: 20rem;margin: 0;color: white;text-shadow: 4px 4px 0 rgba(0, 0, 0, 0.05);
}.timer {display: flex;min-height: 100vh;flex-direction: column;
}.timer__controls {display: flex;
}.timer__controls>* {flex: 1;
}.timer__controls form {flex: 1;display: flex;
}.timer__controls input {flex: 1;border: 0;padding: 2rem;
}.timer__button {background: none;border: 0;cursor: pointer;color: white;font-size: 2rem;text-transform: uppercase;background: rgba(0, 0, 0, 0.1);border-bottom: 3px solid rgba(0, 0, 0, 0.2);border-right: 1px solid rgba(0, 0, 0, 0.2);padding: 1rem;font-family: 'Inconsolata', monospace;
}.timer__button:hover,
.timer__button:focus {background: rgba(0, 0, 0, 0.2);outline: 0;
}.display {flex: 1;display: flex;flex-direction: column;align-items: center;justify-content: center;
}.display__end-time {font-size: 4rem;color: white;
}

JS代码实现逻辑

let countdown;
const timerDisplay = document.querySelector('.display__time-left');
const endTime = document.querySelector('.display__end-time');
const buttons = document.querySelectorAll('[data-time]');function timer(seconds) {// clear any existing timersclearInterval(countdown);const now = Date.now();const then = now + seconds * 1000;displayTimeLeft(seconds);displayEndTime(then);countdown = setInterval(() => {const secondsLeft = Math.round((then - Date.now()) / 1000);// check if we should stop it!if (secondsLeft < 0) {clearInterval(countdown);return;}// display itdisplayTimeLeft(secondsLeft);}, 1000);
}function displayTimeLeft(seconds) {const minutes = Math.floor(seconds / 60);const remainderSeconds = seconds % 60;const display = `${minutes}:${remainderSeconds < 10 ? '0' : '' }${remainderSeconds}`;document.title = display;timerDisplay.textContent = display;
}function displayEndTime(timestamp) {const end = new Date(timestamp);const hour = end.getHours();const adjustedHour = hour > 12 ? hour - 12 : hour;const minutes = end.getMinutes();endTime.textContent = `Be Back At ${adjustedHour}:${minutes < 10 ? '0' : ''}${minutes}`;
}function startTimer() {const seconds = parseInt(this.dataset.time);timer(seconds);
}buttons.forEach(button => button.addEventListener('click', startTimer));document.customForm.addEventListener('submit', function (e) {e.preventDefault();const mins = this.minutes.value;console.log(mins);timer(mins * 60);this.reset();
});

逻辑分析:

  • 当点击button按钮时,调用startTimer方法。
buttons.forEach(button => button.addEventListener('click', startTimer));
  • 在输入框中自定义倒计时时间时,输入enter时调用传入的回调函数。
document.customForm.addEventListener('submit', function (e) {e.preventDefault();const mins = this.minutes.value;console.log(mins);timer(mins * 60);this.reset();
});
  • startTimer函数代码解释
function startTimer() {<!--获取当前点击的button的data-time值,并将其转换成整数-->const seconds = parseInt(this.dataset.time);<!--调用timer函数-->timer(seconds);
}
  • displayTimeLeft代码
<!--计算时分秒,并且展示-->
function displayTimeLeft(seconds) {const minutes = Math.floor(seconds / 60);const remainderSeconds = seconds % 60;const display = `${minutes}:${remainderSeconds < 10 ? '0' : '' }${remainderSeconds}`;document.title = display;timerDisplay.textContent = display;
}
  • displayEndTime代码
<!--计算倒计时结束时间,并且展示-->
function displayEndTime(timestamp) {const end = new Date(timestamp);const hour = end.getHours();const adjustedHour = hour > 12 ? hour - 12 : hour;const minutes = end.getMinutes();endTime.textContent = `Be Back At ${adjustedHour}:${minutes < 10 ? '0' : ''}${minutes}`;
}
  • timer代码
function timer(seconds) {// clear any existing timers清除正在进行的倒计时clearInterval(countdown);<!--获取当前时间-->const now = Date.now();<!--计算多少毫秒后结束倒计时-->const then = now + seconds * 1000;<!--调用displayTimeLeft函数展示倒计时效果-->displayTimeLeft(seconds);<!--展示结束时间-->displayEndTime(then);<!--设置定时器,更新倒计时组建-->countdown = setInterval(() => {const secondsLeft = Math.round((then - Date.now()) / 1000);// check if we should stop it!if (secondsLeft < 0) {clearInterval(countdown);return;}// display itdisplayTimeLeft(secondsLeft);}, 1000);
}

源码下载

Github Source Code

Day29 - Countdown Timer相关推荐

  1. Microsoft Store 里的一个倒数定时器软件 - Free Countdown Timer

    因为工作需要,一直在找一款小巧实用的能够显示在桌面上的倒数定时器 countdown timer,在 Microsoft Store 中找到了一款名叫 Free Countdown Timer 的小软 ...

  2. 易于设置的倒计时页面Easy countdown

    今天开始放假了 什么是 Easy countdown ? Easy countdown 是一个易于设置的倒计时页面.可以设置为倒计时或计时器. 先看看官方提供的动图 安装 在群晖上以 Docker 方 ...

  3. java timer定时执行一次_用java.util.Timer定时执行任务

    classWorker extends TimerTask{ publicvoidrun(){     System.out.println("我在工作啦!");   }} Tim ...

  4. Autojs自动化 实现自动删除公众号文章(通过订阅号助手删除)

    设备 小米9 效果 autojs1 autojs2 代码 UI "ui"; const storage = storages.create("dinyue"); ...

  5. MATALO OPENCART 自适应主题模板 ABC-0679-02

    MATALO OPENCART 自适应主题模板 ABC-0679-02 Matalo is the latest fashion opencart theme from PlazaThemes. Th ...

  6. 前端工程师和设计师必读文章推荐【系列三十三】

    <Web 前端开发精华文章推荐>自2011年6月20号发布第一期以来,历经三年半,总共发布了30多期.今天这篇是2015年第2期(总第33期),希望你能在这里发现有用的资料. 梦想天空专注 ...

  7. Cocoa touch(十):UIDatePicker

    UIDatePicker,日期选取器 typedef NS_ENUM(NSInteger, UIDatePickerMode) {UIDatePickerModeTime, // Displays h ...

  8. unity可以用python编写吗_基于python的Cා代码生成器(用于服务并应用于unity),一个,c,为了,并且,Unity...

    为了满足项目需要,本人需要实现一个c#代码生成器(使用python开发),为此设计了一个语法模板适用于Unity的代码生成器.本次使用了Python的Template模板,使用python开发. ## ...

  9. wordpress常用插件汇总

    WordPress之所以能成为目前最具人气的独立博客程序,除了无数爱好者为它开发的主题外,源源不断的插件支持也是重要的原因之一.wordpress的强大,也是在于无数爱好者源源不断的主题和插件. wo ...

最新文章

  1. PNAS:水稻微生物组
  2. 使用聚类算法(Kmeans)进行数据降维并作为分类算法逻辑回归(logistic Regression)的数据预处理步骤实战
  3. 10行代码实现目标检测
  4. 抛开设计模式,软件设计的微思考
  5. MySQL下载以及安装【windows】
  6. PeerJS 0.1.7:一个用于浏览器内P2P的WebRTC封装器
  7. python3虚拟环境中解决 ModuleNotFoundError: No module named '_ssl'
  8. (转)uml 静态视图关系和关联
  9. 8-字符串的压缩存储
  10. 容器混合云发展引争议,专家亚马逊云科技中国峰会共探讨
  11. Integer与Int
  12. godaddy新建二级域名
  13. python12306源码_春运了,Python大神分享爬取12306车票信息的例子,附抢票源码
  14. 致远SPM之接待管理解决方案
  15. 如何创建一个Java项目
  16. 网上商城购物系统的优势和建站方法
  17. Java 1014 福尔摩斯的约会
  18. XMOS-麦克风阵列方案
  19. 游戏半条命系列人物皮肤壁纸
  20. 王者荣耀微信和QQ服务器怎么一起玩游戏,王者荣耀微信和qq能一起吗 可以一起玩吗...

热门文章

  1. 2022年武汉市经开区企业研发费用投入奖励补贴政策申报条件以及奖补标准!
  2. coresite美国数据中心你了解多少?
  3. OpenCV人脸识别之Eigenface算法(PCA特征脸方法)
  4. jQuery手风琴菜单的制作
  5. 计算机小知识140,电脑小知识140个小技巧(7)
  6. PHP开发小技巧①⑥—提取富文本字符串中的文本内容
  7. 剪辑软件生产力工具pr,ae,达芬奇对比
  8. jupyter notebook 中import torchvision提示ImportError: DLL load failed: 找不到指定的模块
  9. LeetCode hot-100 简单and中等难度,91-100.
  10. 淘宝优惠券可直接应用PNG免抠模板,你知道淘宝优惠券的类型么?