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

news2025/1/13 10:40:01

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

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
    // 每个数字对应一个section
    return clock.querySelectorAll("section");
}

let sections = init();
// 定时更新数字
let myset = setInterval(function(){
    let time = timeGo();  // 时分秒的字符串:240222
    sections.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
    // 每个数字对应一个section
    return clock.querySelectorAll("section");
}

let sections = init();
// 定时更新数字
let myset = setInterval(function(){
    let time = timeGo();  // 时分秒的字符串:240222
    sections.forEach(function(item, index){
        // 取出时分秒的每一位数字,并设置旋转动画
        setTime(time[index], item);
    });
});

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

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

相关文章

从排序算法的艺术看C语言qsort函数的魅力:一场数据的时空穿越

欢迎来到白刘的领域 Miracle_86.-CSDN博客 系列专栏 C语言知识 先赞后看&#xff0c;已成习惯 创作不易&#xff0c;多多支持&#xff01; 目录 一 、回调函数 二、qsort函数 1.qsort函数排序整型数据 2.qsort函数排序结构数据 一 、回调函数 何为回调函数&#xff1…

【JS进阶】第一天

参考视频——黑马程序员 JavaScript 进阶 - 第 1 天 学习作用域、变量提升、闭包等语言特征&#xff0c;加深对 JavaScript 的理解&#xff0c;掌握变量赋值、函数声明的简洁语法&#xff0c;降低代码的冗余度。 理解作用域对程序执行的影响能够分析程序执行的作用域范围理解闭…

三维坐标系之间的转换

一、概括 这个完全是抄别人的&#xff0c;给我自己看的主要是想当我要看的时候我直接能找到&#xff0c;而不用再去网上搜索&#xff0c;后期会吧代码更新上去。 彻底搞懂“旋转矩阵/欧拉角/四元数”&#xff0c;让你体会三维旋转之美_欧拉角判断动作-CSDN博客 在不同的坐标…

Python语法糖

N u m P y NumPy NumPy的 n d i t e r nditer nditer nditer 是 NumPy 提供的一种多维迭代器&#xff0c;用于对多维数组进行迭代操作。它可以替代传统的嵌套循环&#xff0c;在处理多维数组时更加方便和高效。 迭代器可以按照不同的顺序遍历数组的元素&#xff0c;也可以控制…

✅技术社区—通过Canal框架实现MySQL与ElasticSearch的数据同步

Canal 是一个由阿里巴巴开源的&#xff0c;基于 Java 的数据库变更日志解析的中间件&#xff0c;其原理是基于Binlog订阅的方式实现&#xff0c;模拟一个MySQL Slave 订阅Binlog日志&#xff0c;从而实现CDC&#xff0c;主要用于实现 MySQL 数据库的增量数据同步。它主要的使用…

Linux:PostGreSQL|PostGIS部署

由于更换了云服务器&#xff0c;需要重新部署PostGreSQL|PostGIS&#xff0c;所以记录一下Linux CentOS 7 x86-64环境下&#xff0c;PostGreSQL|PostGIS的部署过程。 参考文档&#xff1a;PostgreSQL: Linux downloads (Red Hat family)。 yum安装PostGreSQL 通过yum安装PostG…

PC-DARTS: PARTIAL CHANNEL CONNECTIONS FOR MEMORY-EFFICIENT ARCHITECTURE SEARCH

PC-DARTS&#xff1a;用于内存高效架构搜索的部分通道连接 论文链接&#xff1a;https://arxiv.org/abs/1907.05737 项目链接&#xff1a;https://github.com/yuhuixu1993/PC-DARTS ABSTRACT 可微分体系结构搜索(DARTS)在寻找有效的网络体系结构方面提供了一种快速的解决方案…

网络编程-套接字相关基础知识

1.1. Socket简介 套接字&#xff08;socket&#xff09;是一种通信机制&#xff0c;凭借这种机制&#xff0c; 客户端<->服务器 模型的通信方式既可以在本地设备上进行&#xff0c;也可以跨网络进行。 Socket英文原意是“孔”或者“插座”的意思&#xff0c;在网络编程…

ROS——ROS安装遇到的问题

1、添加ROS软件源 打开终端&#xff0c;将下面这条命令复制到ubuntu的终端执行 sudo sh -c . /etc/lsb-release && echo "deb http://mirrors.ustc.edu.cn/ros/ubuntu/ $DISTRIB_CODENAME main" > /etc/apt/sources.list.d/ros-latest.list2、添加密钥 …

Java面试题总结200道(三)

51、什么是 Spring IOC 容器 Spring 框架的核心是 Spring 容器。容器创建对象&#xff0c;将它们装配在一起&#xff0c;配置它 们并管理它们的完整生命周期。Spring 容器使用依赖注入来管理组成应用程序的 组件。容器通过读取提供的配置元数据来接收对象进行实例化&#xff0…

Windows Docker 部署 Solr 搜索引擎

一、简介 Solr 是 Apache 下的一个顶级开源项目&#xff0c;采用 Java 开发&#xff0c;它是基于 Lucene 的全文搜索服务器。Solr 可以独立运行在 Jetty、Tomcat 等这些 Servlet 容器中。Solr 提供了比 Lucene 更为丰富的查询语言&#xff0c;同时实现了可配置、可扩展&#x…

OpenHarmony4.0对RK3566的烧写过程

前面已经编译的过程搞了比较长的时间,因为遇到了不少问题,老是编译出错,后来经过努力还是编译成功了。 我这里主要针对RK3566的Purple Pi OH开发板,如下图: 因为开源鸿蒙里没有针对这个板的特殊配置,需要下载下面这个文件: purple-pi-oh-patch.zip 这个文件里包含了可…

(二)OpenOFDM频偏校正

频偏校正 This paper [1]解释了频率偏移发生的原因以及如何纠正它。简而言之&#xff0c;有两种类型的频率偏移。第一个称为载波频率偏移 (CFO)&#xff0c;是由发射器和接收器的本地振荡器 (LO) 之间的差异引起的。这种偏移的症状是输入 I/Q 样本&#xff08;时域&#xff09…

国际前十正规外汇实时行情走势app软件最新排名(综合版)

外汇交易&#xff0c;作为当今世界金融市场上一个重要的板块&#xff0c;备受关注和热议。随着金融市场的日益发展&#xff0c;外汇交易也发展成为一个新兴的投资交易渠道。为了更好地满足投资者对外汇市场的需求&#xff0c;外汇实时行情走势app软件应运而生&#xff0c;它为投…

R语言聚类分析-K均值聚类与系统聚类法

一、数据集为firm.csv&#xff0c;给出了22家美国公用事业公司的相关数据集&#xff0c;各数据集变量的名称和含义如下&#xff1a;X1为固定费用周转比&#xff08;收入/债务&#xff09;&#xff0c;X2为资本回报率&#xff0c;X3为每千瓦容量成本&#xff0c;X4为年载荷因子&…

YOLOv9详解

1.概述 在逐层进行特征提取和空间转换的过程中&#xff0c;会损失大量信息&#xff0c;例如图中的马在建模过程中逐渐变得模糊&#xff0c;从而影响到最终的性能。YOLOv9尝试使用可编程梯度信息PGI解决这一问题。 具体来说&#xff0c; PGI包含三个部分&#xff0c;&#xff0…

LeetCode每日一题[C++]-310.最小高度树

题目描述 树是一个无向图&#xff0c;其中任何两个顶点只通过一条路径连接。 换句话说&#xff0c;一个任何没有简单环路的连通图都是一棵树。 给你一棵包含 n 个节点的树&#xff0c;标记为 0 到 n - 1 。给定数字 n 和一个有 n - 1 条无向边的 edges 列表&#xff08;每一个…

数据过滤的练习

定义一个集合&#xff0c;并添加一些整数1&#xff0c;2&#xff0c;3&#xff0c;4&#xff0c;5&#xff0c;6&#xff0c;7&#xff0c;8&#xff0c;9&#xff0c;10&#xff0c;过滤奇数&#xff0c;只留下偶数&#xff0c;并将结果保存起来。 package MyStream;import j…

SAP Activate项目管理方法论路线图

SAP Activate 是 SAP 推出的一种基于敏捷方法论的灵活、快速且引导式的实施方法论&#xff0c;专为加速SAP S/4HANA和其他SAP解决方案的部署而设计。这个方法论结合了最佳实践、引导配置和方法论本身的强大能力&#xff0c;以确保项目的快速实施和成功部署。SAP Activate的核心…

MySQL中出现‘max_allowed_packet‘ variable.如何解决

默认情况下&#xff0c;MySQL的max_allowed_packet参数可能设置得相对较小&#xff0c;这对于大多数常规操作来说足够了。但是&#xff0c;当你尝试执行包含大量数据的操作&#xff08;如大批量插入或大型查询&#xff09;时&#xff0c;可能会超过这个限制&#xff0c;从而导致…