如何使用原生技術寫一個倒計時時鐘

apple_time

A countdown clockjavascript

心血來潮,想作一個蘋果發佈會的倒計時css

訪問地址

frontend.wanghtml

備用地址

barnett617.github.io/apple_timejava

Fork me on github

github.com/barnett617/…jquery

前言

本網站基於github pages服務進行展現css3

過程

步驟以下:git

  1. 首先,網頁標題來個標誌性的蘋果圖標

如何爲網站添加圖標:segmentfault

在<head>標籤中添加<link rel="shortcut icon" href="favicon.ico">,其會從項目根目錄找favicon.ico文件

rel表示將要引用的資源類型,href表示指向資源的URL, <link rel="shortcut icon" href="favicon.ico">中 rel="shortcut icon"是一種固定寫法,不寫或錯寫會致使圖標沒法正常顯示。

  1. 主體佈局

背景

若是要背景鋪滿屏幕,來一個漸變色要怎麼作呢

首先,爲何要用漸變,由於好看啊

其次,爲何漸變不用PS作的圖片,由於CSS3提供了gradients屬性,經過CSS實現其實漸變是由瀏覽器生成的,能夠減小下載的事件和寬帶的使用

既然漸變是瀏覽器生成的,就會涉及到不一樣瀏覽器的支持問題(Safari、Opera、Firefox等)

另外,漸變的方式分爲兩種:線性漸變(Linear Gradients)徑向漸變(Radial Gradients),顧名思義,線性漸變是從一個起點沿着一個方向從一種顏色漸變成另外一種顏色,而徑向漸變是從一個起點沿着一個角度漸變

線性:linear-gradient

徑向:radial-gradient

其參數對於不一樣的瀏覽器有着不一樣的寫法,但基本都是在配置漸變方向和漸變首末的顏色

從上到下(默認)

background: -webkit-linear-gradient(red, blue); /* Safari 5.1 - 6.0 */
background: -o-linear-gradient(red, blue); /* Opera 11.1 - 12.0 */
background: -moz-linear-gradient(red, blue); /* Firefox 3.6 - 15 */
background: linear-gradient(red, blue); /* 標準的語法 */
複製代碼

從左到右

background: -webkit-linear-gradient(left, red , blue); /* Safari 5.1 - 6.0 */
background: -o-linear-gradient(right, red, blue); /* Opera 11.1 - 12.0 */
background: -moz-linear-gradient(right, red, blue); /* Firefox 3.6 - 15 */
background: linear-gradient(to right, red , blue); /* 標準的語法 */
複製代碼

左上角到右下角

background: -webkit-linear-gradient(left top, red , blue); /* Safari 5.1 - 6.0 */
background: -o-linear-gradient(bottom right, red, blue); /* Opera 11.1 - 12.0 */
background: -moz-linear-gradient(bottom right, red, blue); /* Firefox 3.6 - 15 */
background: linear-gradient(to bottom right, red , blue); /* 標準的語法 */
複製代碼

注意:Internet Explorer 9 及以前的版本不支持漸變

上面的是指定方向,也能夠指定角度,以下:

background-image: linear-gradient(to top, #7A88FF, #7AFFAF);
/* 等價 */
background-image:linear-gradient(0deg, #7A88FF, #7AFFAF);
複製代碼

角度指的是過渡在哪一個方向截止,瀏覽器會繪製一條通過元素中心點的假想線。指定的角度就是這條線的角度,同時還指明過分在哪裏結束

0deg 表示元素的頂邊 to top
90deg 表示元素的右邊 to right
180deg 表示元素的底邊 to bottom
270deg 表示元素的左邊 to left

角度解釋圖

若是仍然沒法理解角度如何用,這裏有一個在線演示

除此,透明度(transparent)使用

CSS3 漸變也支持透明度(transparent),可用於建立減弱變淡的效果。

可以使用 rgba() 函數來定義顏色結點。rgba() 函數中的最後一個參數能夠是從 0 到 1 的值,它定義了顏色的透明度:0 表示徹底透明,1 表示徹底不透明。

以下爲從左側徹底透明的紅色到右側徹底不透明的紅色

background: -webkit-linear-gradient(left,rgba(255,0,0,0),rgba(255,0,0,1)); /* Safari 5.1 - 6 */
background: -o-linear-gradient(right,rgba(255,0,0,0),rgba(255,0,0,1)); /* Opera 11.1 - 12*/
background: -moz-linear-gradient(right,rgba(255,0,0,0),rgba(255,0,0,1)); /* Firefox 3.6 - 15*/
background: linear-gradient(to right, rgba(255,0,0,0), rgba(255,0,0,1)); /* 標準的語法 */
複製代碼

以上都是線性漸變

接下來是徑向漸變

radial-gradient(center, shape size, start-color, ..., last-color);
複製代碼

若不指定前面的參數,只指明顏色,則按照默認狀況對顏色進行均勻分佈

能夠根據需求添加任意多個顏色。額外添加的顏色叫色標(color stop)

添加色標後,背景會從第一個顏色過渡到第二個顏色,再從第二個顏色過渡到第三個顏色,直到漸變的最後一個顏色爲止。瀏覽器會平均分佈各個顏色

background: -webkit-radial-gradient(red, green, blue); /* Safari 5.1 - 6.0 */
background: -o-radial-gradient(red, green, blue); /* Opera 11.6 - 12.0 */
background: -moz-radial-gradient(red, green, blue); /* Firefox 3.6 - 15 */
background: radial-gradient(red, green, blue); /* 標準的語法 */
複製代碼

以下爲背景色從左到右開始漸變,最左邊是玫紅,在元素寬度20%的位置變成青色,80%的位置變成黃色,最後是藍色。

linear-gradient(to right, #E94E65, #15A892 20%, #A89215 80%, #1574A8);
複製代碼

使用多色漸變時,第一個顏色和最後一個顏色無需指定位置,由於瀏覽器會嘉定第一個顏色從0%的位置開始,最後一個顏色在100%的位置結束。除非想把第一個顏色或最後一個顏色的位置放在指定的位置開始,才須要專門定位。

若想顏色不均勻分佈,可手動對顏色增長權重

background: -webkit-radial-gradient(red 5%, green 15%, blue 60%); /* Safari 5.1 - 6.0 */
background: -o-radial-gradient(red 5%, green 15%, blue 60%); /* Opera 11.6 - 12.0 */
background: -moz-radial-gradient(red 5%, green 15%, blue 60%); /* Firefox 3.6 - 15 */
background: radial-gradient(red 5%, green 15%, blue 60%); /* 標準的語法 */
複製代碼

shape 參數定義了形狀。它能夠是值 circle 或 ellipse。其中,circle 表示圓形,ellipse 表示橢圓形。默認值是 ellipse。

background: -webkit-radial-gradient(circle, red, yellow, green); /* Safari 5.1 - 6.0 */
background: -o-radial-gradient(circle, red, yellow, green); /* Opera 11.6 - 12.0 */
background: -moz-radial-gradient(circle, red, yellow, green); /* Firefox 3.6 - 15 */
background: radial-gradient(circle, red, yellow, green); /* 標準的語法 */
複製代碼

repeating-radial-gradient() 函數用於重複徑向漸變

/* Safari 5.1 - 6.0 */
background: -webkit-repeating-radial-gradient(red, yellow 10%, green 15%);
/* Opera 11.6 - 12.0 */
background: -o-repeating-radial-gradient(red, yellow 10%, green 15%);
/* Firefox 3.6 - 15 */
background: -moz-repeating-radial-gradient(red, yellow 10%, green 15%);
/* 標準的語法 */
background: repeating-radial-gradient(red, yellow 10%, green 15%);
複製代碼

佈局

須要文字內容水平垂直居中,這就涉及到一個老生常談的問題

一開始隨手一加,使用flex佈局

<body>
  <div class="container">
    <span>倒計時</span>
  </div>
</body>
複製代碼
.container {
  display: flex;
  justify-content: center;
  align-items: center;
}
複製代碼

發現效果並不理想,只水平居中了,垂直方向並無居中

這裏犯了一個flex佈局的理解錯誤,對某個元素進行flex的設置,將影響其子元素,而不是其自己的佈局,因此這裏其實想container這一級水平垂直居中,那麼display: flex;應該加在它的父級,即body的屬性上

而在body上加過多的樣式不是理想的作法,咱們是想以 container 爲頁面根級,因此在其上加flex佈局,而後將其子元素達到居中的效果,那麼要讓 container 做爲頁面根級,則須要其鋪滿屏幕,這裏須要作一些樣式設計。

首先,發現 container 並未鋪滿屏幕,即元素沒有貼邊瀏覽器,這是由於body有一個默認外邊距,會隨着不一樣的瀏覽器有着不一樣的行爲,因此即便 container 高度和寬度100%貼着body,也沒法佔滿屏幕,這就是爲何要對css做全局初始樣式,重置其默認樣式

body {
    display: block;
    margin: 8px;
}
複製代碼

須要在body上進行重置

button, p, pre {
    margin: 0;
}
複製代碼

另外,要讓漸變色的背景鋪滿屏幕,這裏採用了對html和body元素設置高度100%,從而達到自適應,背景總佔滿屏幕的效果

html, body {
  width: 100%;
  height: 100%;
}
body {
  background-image: linear-gradient(45deg, #7A88FF, #7AFFAF);
}
複製代碼

倒計時

接下來,須要一個定時器來展現倒計時

這裏結束時間從簡處理,即便用(後續可優化爲目標時間從目標網站中獲取)

思路

倒計時便是要計算剩餘時間,即目標時間的時間戳減去當下時間的時間戳來作一個格式化顯示,由於當下時間是實時變化的,因此並不須要作特殊處理,只要用目標時間戳(常量) - 當前時間(變量)即可獲得倒計時應該顯示的剩餘時間

這裏國際化是重點

首先來看一下 js 提供的當地時間(根據瀏覽器所設地區顯示相應時間)方法

new Date().toLocaleString()
// "2018/9/4 下午5:04:02"
new Date().toLocaleDateString()
// "2018/9/4"
new Date().toLocaleTimeString()
// "下午5:04:21"
複製代碼

這是 js i18n程序提供的時間格式化方法

Date對象是js原生時間庫,以1970年1月1日00:00:00做爲起點

Date對象做爲普通函數直接調用會返回表明當前時間的字符串(不管是否傳遞參數)

Date()
// "Tue Sep 04 2018 17:23:42 GMT+0800 (中國標準時間)"
Date('2018-08-08')
// "Tue Sep 04 2018 17:23:55 GMT+0800 (中國標準時間)"
Date(2018, 08, 08)
// "Tue Sep 04 2018 17:24:05 GMT+0800 (中國標準時間)"
複製代碼

Date做爲構造函數時,使用new返回一個Date對象實例

new Date()
// Tue Sep 04 2018 17:25:49 GMT+0800 (中國標準時間)
new Date('2018-08-08')
// Wed Aug 08 2018 08:00:00 GMT+0800 (中國標準時間)
new Date(2018, 08, 08)
// Sat Sep 08 2018 00:00:00 GMT+0800 (中國標準時間)
複製代碼

*** 特殊地

普通對象求值,都默認調用其valueOf()方法,而Date實例求值,默認調用toString()方法

var a = 'hello'
a
// "hello"
a.valueOf()
// "hello"
a.toString()
// "hello"

var b = 3
b
// 3
b.valueOf()
// 3
b.toString()
// "3"

var c = new Date()
c
// Tue Sep 04 2018 17:31:30 GMT+0800 (中國標準時間)
c.valueOf()
// 1536053490129
c.toString()
// "Tue Sep 04 2018 17:31:30 GMT+0800 (中國標準時間)"
複製代碼

使用Date構造函數生產日期實例可傳遞各類類型的參數

new Date().valueOf()
// 1536053659322

// 參數爲時間零點開始計算的毫秒數
new Date(1536053659322)
// Tue Sep 04 2018 17:34:19 GMT+0800 (中國標準時間)

// 參數爲日期字符串
new Date('Sep 4, 2018')
// Tue Sep 04 2018 00:00:00 GMT+0800 (中國標準時間)

new Date('Oct 4, 2018')
// Thu Oct 04 2018 00:00:00 GMT+0800 (中國標準時間)

new Date('Oct 4, 2018, 08:59:59')
// Thu Oct 04 2018 08:59:59 GMT+0800 (中國標準時間)

new Date('Oct 4, 2018, 08:61:59')
// Invalid Date

// 參數爲多個整數
// 表明年、月、日、小時、分鐘、秒、毫秒
new Date(2018, 10, 23, 6, 34, 59, 500)
// Fri Nov 23 2018 06:34:59 GMT+0800 (中國標準時間)

new Date('Fri Nov 23 2018 06:34:59')
// Fri Nov 23 2018 06:34:59 GMT+0800 (中國標準時間)
new Date('Fri Nov 23 2018 06:34:59').valueOf()
// 1542926099000
複製代碼

既然這樣,那麼Date()構造方法的參數均可以是什麼格式的呢?

答:任何能夠被Date.parse()方法解析的字符串

注意點

  1. 參數能夠是負整數,表明1970年元旦以前的時間

  2. 參數爲多個整數時,至少須要兩個參數,即年和月,若只傳遞一個參數,將按照毫秒數處理

  3. 參數取值範圍

年:使用四位數年份,好比2000。若是寫成兩位數或個位數,則加上1900,即10表明1910年。若是是負數,表示公元前

月:0表示一月,依次類推,11表示12月

日:1到31

小時:0到23

分鐘:0到59

秒:0到59

毫秒:0到999
複製代碼
  1. 參數若是超出了正常範圍,會被自動折算

  2. 參數只有一個時,使用負整數表示1970年元旦以前的時間,參數爲多個整數時,使用負整數表示從基準日扣去相應的時間

new Date(-1542926099000)
// Wed Feb 09 1921 09:25:01 GMT+0800 (中國標準時間)

new Date(2018, 09, -1)
// Sat Sep 29 2018 00:00:00 GMT+0800 (中國標準時間)
new Date(2018, 0)
Mon Jan 01 2018 00:00:00 GMT+0800 (中國標準時間)
new Date(2018, 0, -1)
Sat Dec 30 2017 00:00:00 GMT+0800 (中國標準時間)
new Date(2018, 1, -1)
Tue Jan 30 2018 00:00:00 GMT+0800 (中國標準時間)
new Date(2018, 1)
Thu Feb 01 2018 00:00:00 GMT+0800 (中國標準時間)
複製代碼

留個疑問,如何求明年的昨天,好比,如今是Tue Sep 04 2018 18:04:58 GMT+0800 (中國標準時間),明年的昨天便是Wed Sep 03 2019 18:04:58 GMT+0800 (中國標準時間),有好的方法能夠提PR,

此處的目標時間以下:

2018 年 9 月 12 日上午 10 點(北京時間 9 月 13 日凌晨 1 點)
複製代碼

後記

沒想到最終呈現出來這麼簡單的一個頁面竟涉及到這麼多東西,並且每個環節均可以細究到不少深層次的東西,這就是web的世界

補充

使用vscode+搜狗輸入法編輯本md文件上傳至github後發現隱藏字符,形如:

出現隱藏字符狀況再現圖片

查得緣由

在mac版vscode的中文輸入法下,按下任意字母,出現中文候選後按刪除鍵,刪除完剛纔輸入的字母再按刪除會出現這個控制字符

mac版的vscode中這個隱藏字符默認隱藏,可經過修改以下配置打開,將文檔中顯示BS的退格符全局搜索並替換爲空便可

//控制編輯器是否應呈現控制字符
"editor.renderControlCharacters": true
複製代碼

原理解析:BS爲ASCII碼中的退格符的Unicode表示法,而全部ASCII控制字符都有一個圖形外觀

參考連接:

jianshu-【CSS】漸變背景

runoob-CSS3 漸變

oschina-介紹 JavaScript 國際化 API

JavaScript 標準參考教程(alpha)之Date

segmentfault-JavaScript 時間與日期處理實戰:你確定被坑過

runoob-jquery

jianshu-如何優雅的選擇字體

相關文章
相關標籤/搜索