JavaScript练手小技巧:数字反转时钟

样式基于博主的这篇文章:

CSS3技巧38:3D 翻转数字效果-CSDN博客

既然可以实现翻转数字了,肯定就可以跟 JS 相结合去完成一些数字展示效果。

比如,数字反转时钟。

为了方便,所有 HTML 数字根据时间动态生成。因此,HTML 只需要一个空空的 div 即可。

HTML结构:

<div class="clock" id="clock"></div>

一、构造数字字符串

为了数字构造方便,首先需要时间数字字符串。

如:2402022。代表了 24点02分22秒。

/*** 构造时间字符串。* 按照时分秒的顺序,从左到右依次取值,如果小于10,则在前面补上“0”。* @returns 时间字符串* @example "240222"*/
function timeGo(){let time = new Date();let hour = time.getHours();let minute = time.getMinutes();let second = time.getSeconds();return   timeToStr(hour) + timeToStr(minute) + timeToStr(second);
}

这里,用到了一个工具函数 timeToStr()。它的作用就是把数字转为字符串,不够10,还会在前面补 0。

/*** 转换数字为字符串,如果小于10,则在前面补上“0”。* @param num 数字* @returns 字符串* @example "02"*/
function timeToStr(num){let newStr = "";if(num<10){newStr = "0"+num;}else{newStr = num+"";}return newStr;
}

二、设置翻转数字反转动画

这个方法是核心。

首先去掉 CSS 代码中,翻转数字的 transition 属性。因此,数字反转后,这里还需要让它回到初始位置,准备下一个数字翻转。这个“归位”,是不能有过渡动画的。

过渡动画,应该通过 js 动态添加。当数字翻转后,就添加过渡 transition 属性。但是,这个时候浏览器是不会有动画的。因为,没有渲染,所以要看到过渡的动画效果,需要强制浏览器渲染。

强制渲染的方式就是让js获取标签的宽高值即可达到。

下面这条语句就是在强制浏览器渲染动画。

   document.body.clientHeight;   // 强制渲染标签,执行动画

关于显示数字,刚开始要设置 after 数字,这个就是代表要展示的数字。

过渡动画执行完毕后,要更新显示的数字 before 为当前数字。所以给翻转的标签添加过渡动画结束事件 transitionend。

此外,不是每次设置数字都要翻转的。如果 after 的数字和要显示的数字一样,就不需要翻转。所以,这个方法还需要有一个判断。如果 after 和要显示的数字一样,就终止函数运行。

/*** 设置数字的旋转动画。* @param numStr 数字字符串* @param id 数字所在的元素*/
function setTime(numStr, id){let tag = id.children;// 如果 after 和要显示的数字一样,就终止函数运行,不需要翻转。if( tag[1].dataset.after === numStr){return;}Array.from(tag).forEach(function(item){item.dataset.after = numStr;});tag[1].style.transition = "all 0.5s linear";document.body.clientHeight;   // 强制渲染标签,执行动画tag[1].style.transform = "rotateX(180deg)";tag[1].ontransitionend = function(){Array.from(tag).forEach(function(item){item.dataset.before = numStr;});tag[1].style.transition = "none";tag[1].style.transform = "rotateX(0deg)";}
}

三、初始化标签

根据时间数字,生成6个 section,每个section显示一个数字内容。

同时,时分秒时间之间还添加一个分号。这个分号放在一个 p 标签里。

/*** 初始化数字的元素。* 动态生成5个数字元素section,每个元素包含两个div,分别代表底部的数字和翻转的数字。* 时分秒之间插入一个冒号, 冒号用一个p标签表示。* @returns 数字元素的数组*/
function init(){let clock = document.getElementById("clock");let html = "";for(let i=0; i<=5; i++){html+=`<!-- 一个数字 --><section><div data-before="x" data-after="x"></div><div data-before="x" data-after="x"></div></section><!-- 一个数字 -->`if(i%2==1 && i!=5){  // 最后一个数字不用冒号html +=`<p class="dots">:</p>`}}clock.innerHTML = html;// 返回数字元素的数组 section// 每个数字对应一个sectionreturn clock.querySelectorAll("section");
}let sections = init();
// 定时更新数字
let myset = setInterval(function(){let time = timeGo();  // 时分秒的字符串:240222sections.forEach(function(item, index){// 取出时分秒的每一位数字,并设置旋转动画setTime(time[index], item);});
});

四、完整代码

/*** 构造时间字符串。* 按照时分秒的顺序,从左到右依次取值,如果小于10,则在前面补上“0”。* @returns 时间字符串* @example "240222"*/
function timeGo(){let time = new Date();let hour = time.getHours();let minute = time.getMinutes();let second = time.getSeconds();return   timeToStr(hour) + timeToStr(minute) + timeToStr(second);
}/*** 转换数字为字符串,如果小于10,则在前面补上“0”。* @param num 数字* @returns 字符串* @example "02"*/
function timeToStr(num){let newStr = "";if(num<10){newStr = "0"+num;}else{newStr = num+"";}return newStr;
}
/*** 设置数字的旋转动画。* @param numStr 数字字符串* @param id 数字所在的元素*/
function setTime(numStr, id){let tag = id.children;if( tag[1].dataset.after === numStr){return;}Array.from(tag).forEach(function(item){item.dataset.after = numStr;});tag[1].style.transition = "all 0.5s linear";document.body.clientHeight;tag[1].style.transform = "rotateX(180deg)";tag[1].ontransitionend = function(){Array.from(tag).forEach(function(item){item.dataset.before = numStr;});tag[1].style.transition = "none";tag[1].style.transform = "rotateX(0deg)";}
}
/*** 初始化数字的元素。* 动态生成5个数字元素section,每个元素包含两个div,分别代表底部的数字和翻转的数字。* 时分秒之间插入一个冒号, 冒号用一个p标签表示。* @returns 数字元素的数组*/
function init(){let clock = document.getElementById("clock");let html = "";for(let i=0; i<=5; i++){html+=`<!-- 一个数字 --><section><div data-before="x" data-after="x"></div><div data-before="x" data-after="x"></div></section><!-- 一个数字 -->`if(i%2==1 && i!=5){  // 最后一个数字不用冒号html +=`<p class="dots">:</p>`}}clock.innerHTML = html;// 返回数字元素的数组 section// 每个数字对应一个sectionreturn clock.querySelectorAll("section");
}let sections = init();
// 定时更新数字
let myset = setInterval(function(){let time = timeGo();  // 时分秒的字符串:240222sections.forEach(function(item, index){// 取出时分秒的每一位数字,并设置旋转动画setTime(time[index], item);});
});

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2871590.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

企业内部培训考试系统培训计划功能说明

培训计划是预设好的一套课程系列&#xff0c;包含课程和考试&#xff0c;分多个阶段&#xff0c;每完成一个阶段就会在学习地图上留下标记&#xff0c;让用户看到自己的努力成果&#xff0c;增强成就感&#xff0c;从而坚持完成课程。 企业内部培训考试系统中如何设置培训计划…

一起玩儿3D打印机——06 Marlin固件的配置(三)

摘要&#xff1a;本文介绍Marlin固件的配置方法 25. 启用EEPROM参数保存功能 #define EEPROM_SETTINGS 打开此功能&#xff0c;会将部分参数保存在打印机中&#xff0c;这样通过屏幕就可以进行调节&#xff0c;而无需重刷固件。 26. 启用板载SD卡支持 #define SDSUPPORT 如…

【QT+QGIS跨平台编译】之七十七:【QGIS_Gui跨平台编译】—【错误处理:字符串错误】

文章目录 一、字符串错误二、处理方法三、涉及到的文件一、字符串错误 常量中有换行符错误:(也有const char * 到 LPCWSTR 转换的错误) 二、处理方法 需要把对应的文档用记事本打开,另存为 “带有BOM的UTF-8” 三、涉及到的文件 src\gui\qgsadvanceddigitizingdockwidge…

WebServer -- 架构图 面试题(上)

目录 &#x1f382;前言 &#x1f33c;流程图 && 架构图 1&#xff09;什么是 WebServer 2&#xff09;服务器基本框架 3&#xff09;Reactor && Proactor 模式 4&#xff09;同步 I/O 模拟Proactor模式&#xff08;Linux&#xff09; 5&#xff09;主从…

C语言基础练习——Day10

目录 选择题 编程题 不用加减乘除做加法 找到所有数组中消失的数字 选择题 1、求函数返回值&#xff0c;传入-1&#xff0c;则在64位机器上函数返回 int func(int x) {int count 0;while (x){count;x x&(x - 1);//与运算}return count; } A 死循环B 64C 32D 16 答案&…

别急,先了解一下什么是REST API吧

1、先想一想Rest API的用途和场景 Rest API的常用场景&#xff1a;前后端分离&#xff0c;前端可多样化&#xff0c;还有与其他系统集成&#xff1a;RESTful API 可以与其他系统进行集成&#xff0c;例如第三方登录、支付和社交媒体平台等。 现在我们知道了如何使用 servlet …

redis 常见的异常

目录 一、缓存穿透 1、概念 解决方案 &#xff08;1&#xff09;布隆过滤器 (2)、缓存空对象 二、缓存雪崩 1、概念 解决方案 &#xff08;1&#xff09;redis高可用 &#xff08;2&#xff09;限流降级 &#xff08;3&#xff09;数据预热 一、缓存穿透 1、概念 缓…

仰卧起坐计数,YOLOV8POSE

仰卧起坐计数&#xff0c;YOLOV8POSE 通过计算膝盖、腰部、肩部的夹角&#xff0c;计算仰卧起坐的次数

分数相加减(C语言)

一、流程图&#xff1b; 二、源代码&#xff1b; # define _CRT_SECURE_NO_WARNINGS # include <stdio.h>int main() {//初始化变量值&#xff1b;int fenmu 2;int result 1;int fuhao 1;//执行循环&#xff1b;while (fenmu < 100){//运算&#xff1b;fuhao (-1…

汽车电子与软件架构概述

汽车电子与软件架构概述 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师 (Wechat:gongkenan2013)。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 本就是小人物,输了就是输了,不要在意别人怎么看自己。江湖一碗茶,喝完再挣扎,出门靠自己…

Sentinel篇:线程隔离和熔断降级

书接上回&#xff1a;微服务&#xff1a;Sentinel篇 3. 隔离和降级 限流是一种预防措施&#xff0c;虽然限流可以尽量避免因高并发而引起的服务故障&#xff0c;但服务还会因为其它原因而故障。 而要将这些故障控制在一定范围&#xff0c;避免雪崩&#xff0c;就要靠线程隔离…

MySQL数据库实现增删改查基础操作

准备工作 安装mysql8.0 (安装时一定要记住用户名和密码)安装数据库可视化视图工具Navicat 请注意⚠️⚠️⚠️⚠️ a. 编程类所有软件不要安装在中文目录下 b. Navicat破解版下载安装教程&#xff1a;&#xff08;由于文章审核提示版权问题&#xff0c;链接不方便给出&#xff…

Docker 哲学 - 容器操作

容器&#xff1a; 创建 停止 删除 强制删除&#xff08;正在运行&#xff09; run stop rm rm -f 列出本地容器&#xff1a; docker ps / docker container ls 镜像&#xff1a; search pull run &#xff1a; …

Orbit 使用指南 03 | 与刚体交互 | Isaac Sim | Omniverse

如是我闻&#xff1a; “在之前的指南中&#xff0c;我们讨论了独立脚本&#xff08; standalone script&#xff09;的基本工作原理以及如何在模拟器中生成不同的对象&#xff08;prims&#xff09;。在指南03中&#xff0c;我们将展示如何创建并与刚体进行交互。为此&#xf…

2024 年(第 12 届)“泰迪杯”数据挖掘挑战赛—— C 题:竞赛论文的辅助自动评阅完整思路与源代码分享

一、问题背景 近年来我国各领域各层次学科竞赛百花齐放&#xff0c;层出不穷&#xff0c;学生参与度也越来越高。随着参赛队伍的增 加&#xff0c;评阅论文的工作量急剧增加&#xff0c;这对评阅论文的人力要求也越来越大。因此引入机器辅助评阅成为竞赛主办方的现实需求。 在…

【解读】保障软件供应链安全:SBOM推荐实践指南(含指南获取链接)

2023年11底&#xff0c;美国NSA&#xff08;National Security Agency&#xff09;、CISA&#xff08;Cybersecurity and Infrastructure Security Agency&#xff09;等多个政府机构部门组成的ESF&#xff08;Enduring Security Framework&#xff0c;持久安全框架&#xff09…

数据结构试卷第九套

1.时间复杂度 2.树&#xff0c;森林&#xff0c;二叉树的转换 2.1树转二叉树 给所有的兄弟节点之间加一条连线&#xff1b;去线&#xff0c;只保留当前根节点与第一个叶子节点的连线&#xff0c;删除它与其他节点之间的连线&#xff1b;然后根据左孩子右兄弟进行调整&#xf…

JavaScript slice()方法详解

在 JavaScript 中&#xff0c;slice() 是一个常用的数组方法&#xff0c;用于从现有数组中提取一部分元素&#xff0c;然后返回一个新的数组。它是一个非常有用的工具&#xff0c;可以帮助你在不改变原始数组的情况下操作数组的子集。本文将介绍 slice() 的基本概念、使用方法、…

算法第二十九天-最长公共子序列

最长公共子序列 题目要求 解题思路 求这两个数组或者字符串的最长公共子序列问题&#xff0c;肯定要用到动态规划。 首先区分两个概念&#xff1a;子序列可以是不连续的&#xff1b;子数组&#xff08;子字符串&#xff09;是需要连续的&#xff1b;另外&#xff0c;动态规划…

WorkPlus Meet局域网视频会议软件的领先解决方案

局域网视频会议软件在现代企业中发挥着重要的作用&#xff0c;而在众多选项中&#xff0c;为何选择WorkPlus Meet作为局域网视频会议软件&#xff1f; 选择局域网视频会议软件时需要考虑到企业的需求。WorkPlus Meet提供了稳定、高效的局域网视频会议功能&#xff0c;能够满足…