基於zepto的移動端輕量級日期插件

前言

作過移動Web開發的同窗都知道,移動端日期選擇是很常見的需求。在PC端,咱們有很豐富的選擇,比較出名的就有MobiscrolljQuery UI Datepicker。我的看來,這些插件存在的兩個顯而易見的問題,第一是太重的依賴,對於jQuery的插件,已經強制依賴了80多k的龐然大物,把不少移動端項目拒之門外;第二是太過強大的功能,不少插件花百分之八十的時間去完善插件百分之二十炫酷的額外功能,致使代碼量變大,配置繁雜。因此一款少依賴輕量級使用簡單的移動端日期選擇插件是很是必要的。本文簡單介紹近來寫的一款基於zepto的移動端輕量級日期插件--date_pickercss

插件設計原則

只保留最必要的功能

日期選擇插件無非就是能夠進行年、月、日選擇,而且提供必要的年月切換動畫特效,至於什麼最小時間、最大時間、主題定製,概不在本插件功能範圍。html

保留必要的依賴

本插件雖然說是基於zepto,實際上還隱性依賴了Github上面一個比較牛的庫fastclick。咱們知道,移動端點擊事件處理有兩個常見的問題:(1)移動端click事件有300ms,一般採用touch事件來代替click事件來提升靈敏性;(2)touch事件會存在穿透的問題,通常插件都不用touch事件;基於這兩個問題,fastclick作了兼容,只須要簡單調用它提供的api就可以愉快得和本來同樣調用click事件,因此這個依賴不能省。至於依賴zepto,其實是無關緊要的,一來博主平時工做都是寫原生js的,不用插件也沒多大的感受,二來插件受衆面就會小一些。不過鑑於zepto在移動端已然和zepto在PC端同樣如魚得水,就絕不客氣採用了。android

既可以支持模塊化又能本地引用文件使用的

久遠一點的插件基本都是讓你下載一個文件,而後用script去引用,這樣本無可厚非,只不過放着最大的包管理器npm不用,豈不是對不起頁面仔這個稱號。因此本插件支持文件引用也支持CMD方式的模塊引用。git

功能介紹

直接上圖:
圖片描述github

技術細節

transitionEnd事件

插件的主面板是當前月份的天數詳情,若是點擊上一個月或者下一個月插件須要計算出上一個月或者下一個月的天數信息,而後插入到DOM節點中。在插入到DOM節點以後,就須要採用動畫效果來顯示最新的一月而且褪去老的一個月,採用的方式是CSS2d轉化加過渡。咱們須要處理的就是在舊的一個月褪去看不見的時候及時從DOM樹中刪除,否則若是用戶一直點下一個月或者上一個月的話,內存會炸的。爲了實現這個移除功能,一個辦法是採用setTimeout事件在特定的時間去刪除節點,通過嘗試,發現因爲Javascript定時器不許確的特性和先後一個月切換帶來的邏輯複雜度增長,這種方案很不可行。
因而,本插件採用了第二個方案:transitionEnd事件。直接引用一下MDN的介紹:web

The transitionend event is fired when a CSS transition has completed. In the case where a transition is removed before completion, such as if the transition-property is removed, then the event will not fire. The event will also not fire if the animated element becomes display: none before the transition fully completes.npm

也就是隻要你不去隨便亂動元素的CSS屬性,在動畫完成的時候,你就能夠執行相應的操做(刪除節點)。
再來看看兼容性:
圖片描述
對於移動Web開發足矣!api

最後就是在綁定事件的兼容性問題,不一樣廠商對於這個事件的定義並不一致,好比IOS裏面監聽的是transitionend事件,可是在安卓裏面監聽transitionend事件徹底沒反應,通過一番Google,發現安卓須要監聽webkitTransitionEnd事件。爲了解決綁定事件時候的兼容性問題,就須要檢測瀏覽器到底支持哪一種事件。下面貼上Stackoverflow上面一個問答的代碼片斷:瀏覽器

function whichTransitionEvent() {
        var t,
            el = document.createElement('fakeelement');
            transitions = {
                'OTransition'       :'oTransitionEnd',
                'MSTransition'      :'msTransitionEnd',
                'MozTransition'     :'transitionend',
                'WebkitTransition'  :'webkitTransitionEnd',
                'transition'         :'transitionEnd'
            };

        for(t in transitions){
            if( el.style[t] !== undefined ){
                return transitions[t];
            }
        }

        return false;
    }

安裝使用

安裝

支持下面兩種方式模塊化

  • git clone以後直接拷貝引用bin文件夾下面的datepicker.min.cssdatepicker.min.js

  • 從npm下載安裝:npm install --save date_picker

使用

  • 引用樣式datepicker.min.css

  • 引用datepicker.min.js或者引用模塊var DatePicker = require('date_picker');

  • 實例化組件,綁定插件日期選擇完成以後的回調函數

var _date = document.getElementById('date');

    var datePicker = new DatePicker({
        confirmCbk: function(data) {
            _date.value = data.year + '-' + data.month + '-' + data.day;
        }
    });

    _date.onfocus = function(e) {
        _date.blur();
        datePicker.open();
    };

插件外置兩個API: openclose,其中特別注意上面demo中_date在獲取焦點以後裏面強制去除了焦點,是爲了不安卓下面爲input標籤設置readonly屬性並不能禁止原生鍵盤彈出的問題。

在線Demo

點擊連接在PC上查看效果或者手機掃碼可直接在手機上查看效果:
圖片描述

小結

本插件代碼託管在Github上面,倉庫地址爲:https://github.com/yuanzm/simple-date-picker
npm上面的倉庫地址爲:https://www.npmjs.com/package/date_picker
最後打個小廣告,歡迎follow個人github: https://github.com/yuanzm

參考資料

http://stackoverflow.com/questions/13823188/android-4-1-change-transition-and-webkittransition-defiend-how-to-properly-de

相關文章
相關標籤/搜索