並不簡單的翻頁時鐘(二):JavaScript篇

上一篇 : 並不簡單的翻頁時鐘(一):樣式篇

思路

  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)






註釋寫的還是比較全的,結合思路比較容易看懂。 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章