My studying notebook

2008/06/23

[Javascript & Css] CountDown

6/23/2008 09:30:00 PM Posted by Kai-Chu Chung , , 1 comment

google code jam 2008的首頁中,有一個斗大的CountDown,正在一秒一秒的倒數著報名截止的時間(07/16/2008 23:00:00 UTC)。看到這一個Counter就想起讀研究所的時候,幫老師帶大學部的助教,在作業上傳的頁面也作了一個CountDown,倒數著學生上傳最後的期限(每一次Reload時間才會改變),不過看起來的品質就沒有這一個的好,所以想說就試著分析一下。

最主要的部份為 Javascript + Css + DHTML 構成,主要由Javascript帶入DOM元素計算,並更新DOM元素CSS屬性來顯示不同時間。


Live Demo | Download

HTML
<span id="day0" class="num_0">0</span>
<span id="day1" class="num_0">0</span>
<!-- day -->
<span class="hp_counter_divider">:</span>
<span id="hour0" class="num_0">0</span>
<span id="hour1" class="num_0">0</span>
<!-- hour -->
<span class="hp_counter_divider">:</span>
<span id="min0" class="num_0">0</span>
<span id="min1" class="num_0">0</span>
<!-- minute -->
<span class="hp_counter_divider">:</span>
<span id="sec0" class="num_0">0</span>
<span id="sec1" class="num_0">0</span>
<!-- second -->

Javascript

<script type="text/javascript">
// create the countdown
new Countdown({
toDate: new Date(Date.parse("07/04/2008 23:00:00 UTC")),
dayElements: [el("day0"), el("day1")],
hourElements: [el("hour0"), el("hour1")],
minuteElements: [el("min0"), el("min1")],
secondElements: [el("sec0"), el("sec1")]
});
</script>

Countdown是在Javascript中使用了OO中封裝的技巧,在Countdown Function中定義了屬性(toDate, dayElement, hourElements, minuteElements, secondElements),上由el(var el = function(n) { return document.getElementById(n); })直接帶入DOM元素中相對應的值進行計算與更新CSS屬性

counter.js

function Countdown(config) {
this.toDate = config.toDate;
this.dayElements = config.dayElements;
this.hourElements = config.hourElements;
this.minuteElements = config.minuteElements;
this.secondElements = config.secondElements;
this.timer = undefined;

/**
* Updates the countdown display.
*/
this.update = function () {
var elapsed = (this.toDate.getTime() - (new Date()).getTime()) / 1000;
this.setDisplay(
this.age(elapsed, Countdown.DAY), this.age(elapsed, Countdown.HOUR), this.age(elapsed, Countdown.MINUTE), this.age(elapsed, Countdown.SECOND));
};

/**
* returns the age
*/
this.age = function (seconds, t) {
if (seconds <= 0) {
return[0, 0];
}
var s = ((Math.floor(seconds / t.unit)) % t.length).toString();
return (s.length < 2) ? ["0", s] : [s.substring(0, 1), s.substring(1, 2)];
};

/**
* Starts the countdown timer
*/
this.setDisplay = function (day, hour, minute, second) {
this.display(day, this.dayElements);
this.display(hour, this.hourElements);
this.display(minute, this.minuteElements);
this.display(second, this.secondElements);
};

/**
* Does the display
*/
this.display = function (num, els) {
els[0].innerHTML = num[0];
els[1].innerHTML = num[1];
els[0].className = "num_" + num[0];
els[1].className = "num_" + num[1];
};

// start timer
var that = this;
this.timer = setInterval(function () {
that.update()
},
250);
return;
}

/**
* some constants
*/
Countdown.DAY = {
unit: 86400,
length: 100000
};
Countdown.HOUR = {
unit: 3600,
length: 24
};
Countdown.MINUTE = {
unit: 60,
length: 60
};
Countdown.SECOND = {
unit: 1,
length: 60
};


counter.js中,一樣利用this.property封裝屬性、function()表示Method,計算出與截止時間的時間差,換算成 DD,HH,MM,SS 格式。在this.display中動態改變DOM元素值與CSS屬性


CSS

google code jam 2008的首頁CountDown中,Days,Hours,Mins,Secs皆是利用CSS background-position 屬性來顯示,在CSS中預先定義好0-9每個數字的background-position,在DOM元素改變CSS屬性時,即可套用CSS不同數字的背景圖

/* Number "0" */
#CounterCount span.num_0 {
background - position: 0px 4px;
}
/* Number "1" */
#CounterCount span.num_1 {
background - position: 0px - 21px;
}
/* Number "2" */
#CounterCount span.num_2 {
background - position: 0px - 46px;
}



ps. OOPS implementation in JavaScript可以參考Exploring OOPS - JavaScript Style serials by mastergaurav (code project)
ps. 07/16/2008 23:00:00 UTC, UTC(Coordinated Universal Time), 台灣為東8區,所以時間為UTC+8即可

1 comment:

  1. 這個計時器我用了很久了,
    真是我目前用過最好用的,
    唯一缺點是只能用一個,
    我懶得改阿>w<

    ReplyDelete