[javascript]簡單 方便 易折騰的日曆控制項,純javascript支援鏈式文法,核心代碼只有5行

來源:互聯網
上載者:User

又重複造了個輪子,重複造輪子當然要有優點要不就沒有存在價值。使用簡單,方便。只要5行代碼就可產生年曆。

input date已經是一個原生控制項opera和chrome已經支援,日曆控制項邏輯比較複雜,要做到盡善盡美也是不容易的,也是比較鍛煉編碼的,所以學習意義大於實際意義。而且這個控制項也是多年心愿,最近有時間寫寫停停,終于堅持下來就拿來和大家分享了。

 

 

傳送門

 

特點

1.此日曆外掛程式特點在於簡單易用,要保證功能實現最低要求一個參數。

2.個人化配置有強大的自訂事件和多個個人化參數可選。

3.採用原型繼承,擴充派生非常方便。

4.跨瀏覽器,保證可用性。

5.採用表格做載體,無樣式也可以正常使用功能。

6.緩衝,已產生月份資料。使資料持久化,減少計算。

7.無樣式支援,功能依然健在。

應用展示

a.

b.

c.

 

技術總結

1.主要痛點不是日期演算法,而是select控制項和表格所帶來的問題。select和表格都有一套自己的dom api,來操作和訪問。尤其是產生日曆table的演算法非了一些時間,而且ie瀏覽器上。innerHTML 屬性,table tbody tfoot tr都是唯讀,所以對技術選型有一些幹擾。中間使用了insertRow這樣的方法未果,採用分辨瀏覽器採用不同方案也行不通後,過段採用整個table都用拼字串的方式。雖然效率不一定比產生dom節點存入變數修改高,但是結果卻是最好的。

2.select主要問題在於序號和長度差,要訪問selectedIndex,設定select的值都要小心這個變化。

3.Date對象的序號問題,年 日都是從1開始,月份是從0開始,這些差別和人類習慣的處理帶來一定成本。

可見初期,技術儲備和技術選型的重要性。

其實日期核心演算法只有5行代碼而已,想要產生一個可用的日期控制項20行內代碼足夠,由於和日期控制項相關的控制項出來帶來了大量代碼。

 

核心代碼

 

1。計算某個月有多少天,2012.6月到底有多少天呢?我們要是知道6月最後一天是多少號,不就知道6月有多少天了嗎。

new Date('2012,6,0').getDate();最簡單最短 //chrome不支援用字串new Date('2012,6,0')格式建立日期, 但支援new Date('2012','6','0');這點要注意 而safari沒有問題非常詭異

通用的

(new Date(+(new Date(2012, 7, 1)) - 86400000)).getDate();

下個月的一號減去一天,就是當月最後一天

 

2.知道了當月有多少天還不行,要知道當月1號是要放在什麼位置,如果知道1號是星期幾不就可以知道1號在什麼位置了嗎。

new Date(2012, 7,1).getDay();

 

3.產生一個月的日曆,代碼很簡單只有5行

for (var i = 0; i < row; i++) {  html.push('</tr>');   for (var j = 0; j < 7; j++) {      html.push((cell-- <= offset && days > 0) ? ('<td ' + (that.Date > new Date(y, m, days + 1) ? 'class="oldDay"' : '') + (y === that.Year && m === that.Month && days === that.Day ? 'class="currentDay"' : '') + ' title="'+y+that.style+(m+1)+that.style+days+'">' + (days--) + '</td>') : '<td></td>');   }   html.push('<tr>');
}

大家可能要懷疑為什麼先寫的是 </tr>結束標籤,開始產生日曆的時候採用的是倒序迴圈,用li標籤,後面發現無樣式時不能使用,所以改用table但這一方式保留下來,日期也是按照從後往前產生的。然後調用數組的reverse反向join就正序了。

 

4.一個執行個體的6月份資料和另外一個執行個體的6月份資料有不同點麼,或者重複使用6月份資料需要每次都計算麼,答案顯然不是。相同月份的資料多次使用要是只計算一次的話就可以大大提高效率,減少計算次數。

那麼這就牽扯到資料持久化的問題,怎樣把資料持久化呢或者暫時持久化?答案是把資料儲存在類的屬性上隨用隨拿。

 

var key = '_date_:' + Y + ':' + M;indicotar.cache[key] || (indicotar.cache[key] = that.getDateString(Y, M));

按照年月產生一個key,如果沒有資料就調用方法產生資料存入對應key的value。以後只用只用取出,合并字串即可。

 

 

API

constructor:Cal(可以自行修改無依賴);
執行個體化:new Cal(document.body);
傳回值:執行個體對象;

參數
Node *htmlNode nodeType為1的節點,控制項會被append此節點內
Object O 配置控制項選擇性參數
Number O.Y 設定的年份,預設當年,範圍(1970-當年+10)
Number O.M 設定的月份,預設當月,範圍(1-12)
String O.hasTitle 是否有日期控制欄,預設有'true'
String O.hasFoot 是否有腳註用來顯示年月,預設無'false'
String O.style 日期分隔符號,預設'-'
Number O.startYear 開始年,預設2006
Number O.endtYear 結束年,預設當年加10
Function O.ongetdate 使用者點擊日期儲存格時觸發,this指向執行個體,第一個參數為日期對應數組
Function O.onrender 控制項插入值dom樹時觸發,this指向執行個體,第一個參數為控制項對應的dom節點
Function O.ongetdatestring 獲得月份所對應的日期文字時觸發,this指向執行個體,第一個參數為字串
Function O.oncalframe 組成完畢控制項node架構時觸發,this指向執行個體,第一個參數為對應的dom節點
Function fn 類的回呼函數,產生控制項後觸發

 

執行個體方法
方法名 參數 傳回值
createDay Y:number/string(2012),M:number/string(0-11) 執行個體(1儲存日期文字至Cal的cache中,是資料持久化;2調用render)
render node:(this.elems),key:string('_date_:2012:0'),Y:number(2012),M:number(0-11) 執行個體(渲染控制項至dom樹)
getDateString Y:number(2012),M:number(0-11) htmlString
toString   string '2012-12-12' (擷取選中日期對應的字串)
valueOf   Array [2012,12,12] (擷取選中日期對應的數組)
hide   執行個體 (隱藏控制項)
show   執行個體 (顯示控制項)
setCss Object({'font-size':'12px','width':'300px'}) 執行個體 (為控制項添加樣式)
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.