課程前言:
慕課網(wǎng) -- DatePicker組件開發(fā)
課程準(zhǔn)備:
HTML、CSS、JavaScript基礎(chǔ)、瀏覽器事件
靜態(tài)結(jié)構(gòu)的編寫、日歷數(shù)據(jù)、數(shù)據(jù)渲染、事件處理
靜態(tài)結(jié)構(gòu)的編寫:

header分為三部分,向上翻頁的button,向下翻頁的button,還有就是中間的當(dāng)前月份顯示。
body部分是一個(gè)表格的呈現(xiàn),分為兩個(gè)部分,表頭是周一到周日的呈現(xiàn),表格內(nèi)容是每一個(gè)單元格就是一個(gè)日期。
組件的樣式命名,會(huì)比較長(復(fù)雜),開發(fā)的是一個(gè)組件,那這個(gè)組件就會(huì)被應(yīng)用到各個(gè)頁面上,如果過于簡(jiǎn)單,就會(huì)跟頁面上的元素class命名沖突,帶來不必要的麻煩。因此,組件的樣式命名就比較獨(dú)特,可以長一點(diǎn)。
a元素實(shí)現(xiàn)按鈕,是因a自帶手形圖標(biāo)。一般來說,可點(diǎn)擊的按鈕都需要一個(gè)提示。
靜態(tài)樣式的編寫:
box-shadow:給盒子一個(gè)懸浮于頁面的效果,box-shadow:2px2px8px2pxrgba(128,128,128,.3);
級(jí)聯(lián)選擇器:避免與外界發(fā)生沖突。background-color:#f0f0f0; 它是區(qū)別于白色的背景色。為了使字體符號(hào)更像圖標(biāo),會(huì)設(shè)置字體的樣式,font-family:Serif; a標(biāo)簽有href屬性時(shí),就會(huì)有下劃線。
border-collapse:collapse;是說,table中,相鄰的兩個(gè)表格線會(huì)折疊一條。選中狀態(tài)下 shift+cmd+上下箭頭即上下移動(dòng);
日期對(duì)象:
new Date (year,month-1,date) 其中,月份需要-1.越界自動(dòng) 進(jìn)退位,還有 getFullYear() ,getMonth() , getDate() .
getYear() ?是說,距離 1900 年多少年,比如2017 getYear() 后就是 117年;但getFullYear() 就是 2017年了。
getDay() 當(dāng)前日期在一周中是周幾。
當(dāng)月第一天 new Date(year, month-1, 1) 日期指定1,月份是從0開始的,所以要-1,year也都是正常的 2017 呀等。
當(dāng)月最后一天 new Date(year, month, 0) 日期指定 0,月份是month,沒有減1,其實(shí)就是下個(gè)月咯,下個(gè)月的第0天,表示上一個(gè)月的最后一天。(因月份的最后一天,不一定都是31,因此,我們用 下一個(gè)月的 0 來表示 這個(gè)月的最后一天。這是利用了日期的自動(dòng)進(jìn)退位。)

星期一 到 星期天,[1,2,3,4,5,6,0] ,這個(gè)數(shù)組是 getDay() ?的返回值。一個(gè)星期的開始,是從周天開始的,也就是0開始的,你知道為什么嗎???
獲取日歷數(shù)據(jù):
利用JS獲取日歷的核心數(shù)據(jù)

日期數(shù)據(jù)的渲染:
有時(shí)聊渲染,其實(shí)就是一個(gè)html。

整個(gè)過程細(xì)心就好了,其實(shí)就是比較繁瑣。 < 小于號(hào),>;大于號(hào),因普通的跟看起來有點(diǎn)不同,那就調(diào)整一下字體就好了。span中間是當(dāng)前月份的顯示,都是從 monthData中拿到,前期數(shù)據(jù)的準(zhǔn)備非常重要。
輸入框的展開與收起:
優(yōu)化著手點(diǎn)有兩方面:
1.當(dāng)用戶點(diǎn)擊輸入框的時(shí)候,日期組件才可以顯示,不能一打開頁面,它就在,太不友好了;
2.目前的日期組件的主題結(jié)構(gòu) wrapper header body是占據(jù)文檔流的,如果頁面里還有其他的內(nèi)容,會(huì)因日期的出行,下移的,因此將其樣式改為絕對(duì)定位。
元素的顯示與隱藏:方式很多樣;最通用是通過class來控制,默認(rèn)是隱藏,除非多了一個(gè) block 的樣式,后者覆蓋前者,wrapper就才顯示出來。 ?.classList.remove 與 .classList.add 的 使用。 ?isOpen 布爾值 來記錄當(dāng)前是關(guān)閉狀態(tài)還是展開狀態(tài)。
日期組件的絕對(duì)定位:目標(biāo)是希望它出現(xiàn)在輸入框的下方,所以就要先找到輸入框目前在頁面的哪個(gè)位置呢: var left = $input.offsetLeft; ?var top = $input.offsetTop; ? var height = $input.offsetHeight; ? $wrapper.style.top = top + height + 9 +'px'; ? $wrapper.style.left = left + 'px';(切記,這里用style給寬高的時(shí)候,加上 px 呢。)

月份切換:
本節(jié)課的出發(fā)點(diǎn):左右按鈕切換時(shí),進(jìn)入上一月,或者下一月。初始化的時(shí)候,給按鈕綁定事件。但這種情況,是在組件初始化的時(shí)候才有效,事件只綁定了一次;但頁面渲染之后,內(nèi)容里是根據(jù)按鈕再重新渲染的,我們的按鈕也是感覺HTML字符串再重新渲染的,因此就會(huì)有按鈕不斷的銷毀與重建。

datepicker.render('prev')? datepicker.render('next') 是誰:

日期點(diǎn)擊選中:
data-*是一個(gè)比較新的API,老的瀏覽器不能使用。*是要替換成自己命名的字符。為一個(gè)標(biāo)簽添加一個(gè)此屬性后,js取值的時(shí)候是: target.dataset.d; ? ? target:添加此屬性的標(biāo)簽對(duì)象 ? ?dataset:固定寫法 ? ?d:添加的屬性名的后半部分,即data-*中“-”后自己命名的字符。


日期組件的使用:

調(diào)用方法由繁入簡(jiǎn),最后只有 .init 里,傳一個(gè)樣式。

而一個(gè)日期組件的出現(xiàn),就依靠這個(gè)輸入框了。而這個(gè)輸入框的樣式,因?yàn)椴粚儆诮M件,因此就寫在頁面里咯~
課程總結(jié)(組件開發(fā)流程):
使用HTML合理規(guī)劃組件結(jié)構(gòu);
為組件編寫美觀的樣式;
如何使用JavaScript獲取組件所需數(shù)據(jù);
將數(shù)據(jù)與HTML結(jié)構(gòu)結(jié)合;
用戶事件處理;

整個(gè)日期組件的出現(xiàn),就是從 init 開始,然后 init 在綁定相關(guān)的點(diǎn)擊操作之前,首先調(diào)用 render 來渲染這個(gè)的日期組件;然后,render里,寫的是 日期組件中的數(shù)據(jù),還有左右兩邊的上下按鈕;render里的數(shù)據(jù),則是從 buildUi 里來的,包括樣式,都是一致的。
小技能:
var$input =document.querySelector('input');
$wrapper.classList.add('ui-datepicker-wrapper-show');
$wrapper.classList.remove('ui-datepicker-wrapper-show');
if(!$target.classList.contains('ui-datepicker-btn'))return;
if($target.tagName.toLowerCase() !='td')return;
不寫備注了,試試看,能否想起來啦。
后續(xù)可完善的功能:
如何在移動(dòng)端使用日期組件;
當(dāng)頁面比較復(fù)雜的時(shí)候,如何處理,彈出框的位子;
如何標(biāo)記上一個(gè)月與下一個(gè)月的日期,使它們擁有不同的樣式;
某一些日期可點(diǎn),某一些日期不可點(diǎn)。
寫在最后,寫給自己:
整個(gè)組件開發(fā)的核心,是日期數(shù)據(jù)的獲取,那老師都已經(jīng)給出思路了,我是否愿意寫一寫可完善的功能;如果我覺得JS不那么的熟悉,是否可以使用React重新開發(fā)該框架呢?如果想要重寫,大概要多久呢?