欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

并不简单的翻页时钟(二):JavaScript篇

程序员文章站 2022-03-24 18:38:21
...

上一篇 : 并不简单的翻页时钟(一):样式篇

思路

  1. 初始化Flipper类,包括对应的节点(时间的每一位,动画的持续时间,以及现在的时间和下一秒的时间)
  2. 根据option参数(是否是十二小时制)来初始化时钟
  3. 为时间上的每一位进行判断 : 这个数位上的时间照上一秒是否有变化->有=>为其添加对应css类名,前边执行翻转动画,并在动画执行结束后移除类名,后边准备下一秒的时间。->没有=>不变,continue进入下一次循环判断

代码

//Filpper类,每个实例对应时间上的一位,即一个翻页的部分
var Flipper =/**@Class*/ (function () {
    function Flipper(node , currentTime , nextTime) {
        //this指向实例化的对象
        this.isFlipping=false;
        this.duration=600;
        this.flipNode=node;//.flipNumber
        this.frontNode=node.querySelector(".front");
        this.backNode=node.querySelector(".back");
        this .setFrontTime(currentTime);
        this.setBackTime(nextTime);
    }

    Flipper.prototype.setFrontTime=function (time) {
        this.frontNode.dataset.number=time;//设置front的data-number
    };
    Flipper.prototype.setBackTime=function (time) {
        this.backNode.dataset.number=time
    };

    /**
     * 前边显示当前时间,后边准备即将到来的时间
     * 给.flipNumber添加一个running类名,启动动画
     * 600ms(css中的动画时间)后,将.flipNumber的.running类名移除
     *前边显示即将到来的时间(即下一阶段的当前时间)
     */
    Flipper.prototype.flipDown=function (currentTime , nextTime) {
        var _this=this;
        this.isFlipping=true;
        this.setFrontTime(currentTime);//当前时间显示在前边
        this.setBackTime(nextTime);//后边准备即将到来的时间
        this.flipNode.classList.add("running");//给flipNumber添加running类,开始动画

        setTimeout(function () {
            _this.flipNode.classList.remove("running");
            _this.isFlipping=false;
            _this.setFrontTime(nextTime);
        } , this.duration);//600ms 后移除动画
    };
    return Flipper;
} () );

/**
 * 获取时间字符串
 * @param date 日期时间字符串 , option 是否为十二小时制
 * @returns {string}
 */
var getTimeFromDate=function (date , option ) {
    var time= date
        .toTimeString()//时间=>字符串
        .slice(0,8)//取前八位hh:mm;ss
        .split(":")//根据:分隔成数组
        .join("");//=>字符串
    var hour=parseInt(time.slice(0,2));
    var rest=time.slice(2);
    var ampm=document.getElementById("ampm");

    //当选择十二小时制
    if(option){
        if ( hour>12 ){
            hour=hour-12;
            hour=formatHour(hour);
            time=hour+rest;
            ampm.innerText="PM";
        }
        else {
            hour=formatHour(hour);
            time=hour+rest;
            ampm.innerText="AM";
        }
    }
    else {
        hour=formatHour(hour);
        time=hour+rest;
    }
    return time;
};

function formatHour(hour) {
    hour=hour.toString();
    return hour.length==1? "0"+hour : hour;
}

//存放时钟每一位的实例化对象的数组
var flippers=[]
//是否是十二小时制
var isTwelve=false


/**
 * 初始化时钟
 * @param format 时间格式
 */
function initClock(format) {
    isTwelve=format ==12;
    var flips=document.querySelectorAll(".flipNumber");
    var now=new Date();
//当前时间(由于翻页,实际上是上一秒的时间)
    var nowTimeStr=getTimeFromDate( new Date(now.getTime()-1000) , isTwelve );
//即将到来的时间(实际上是当前时间)
    var nextTimeStr=getTimeFromDate( now , isTwelve );
//将节点集合转换为数组,为时间的每一位实例化Flipper对象,返回对象集合flippers
    flippers= Array.from(flips).map(function (flip , i) {
        return new Flipper(flip , nowTimeStr[i] , nextTimeStr[i]);
    });
}

/**
 * 每秒执行一次,为时钟的每一位判断是否应该翻转并执行翻转动画
 */
setInterval(flipEverySecond, 1000);
function flipEverySecond() {
    var now=new Date()
    var nowTimeStr=getTimeFromDate( new Date(now.getTime()-1000) , isTwelve);
    var nextTimeStr=getTimeFromDate(now , isTwelve);
    for (let i=0 ; i<flippers.length ; i++){
        //如果前后时间一样,也就是该位置上的时间没有变化,则跳过,进入下一次循环
        if (nowTimeStr[i] === nextTimeStr[i]) continue;
        flippers[i].flipDown(nowTimeStr[i] , nextTimeStr[i]);
    }
}

/**
 * 时钟设置
 */
//切换十二小时制
function toggleFormat () {
    var controlFormat=document.getElementById("controlFormat");
    var twelve=document.getElementById("twelve");
    if (controlFormat.checked) {
        twelve.style.display="block"
        initClock(12)
    }
    else{
        twelve.style.display="none"
        initClock(24)
    }

}
//切换秒钟显示
function toggleSecond() {
    var seconds=document.getElementsByClassName("second");
    var controlSecond=document.getElementById("controlSecond")
    console.log(controlSecond.checked)
    if (controlSecond.checked) {
        for( let second of seconds){
            second.style.display="none"
        }
    }
    else {
        for( let second of seconds){
            second.style.display="block"
        }
    }
}

//初始化时钟,默认24小时制
initClock(24)






注释写的还是比较全的,结合思路比较容易看懂。