基于zepto的移动端轻量级日期插件--date_picker


Posted in Javascript onMarch 04, 2016

前言

做过移动Web开发的同学都知道,移动端日期选择是很常见的需求。在PC端,我们有很丰富的选择,比较出名的就有Mobiscroll和jQuery UI Datepicker。个人看来,这些插件存在的两个显而易见的问题,第一是过重的依赖,对于jQuery的插件,已经强制依赖了80多k的庞然大物,把很多移动端项目拒之门外;第二是太过强大的功能,很多插件花百分之八十的时间去完善插件百分之二十炫酷的额外功能,导致代码量变大,配置繁杂。所以一款少依赖、轻量级和使用简单的移动端日期选择插件是非常必要的。本文简单介绍近来写的一款基于zepto的移动端轻量级日期插件--date_picker。

插件设计原则

只保留最必要的功能

日期选择插件无非就是可以进行年、月、日选择,并且提供必要的年月切换动画特效,至于什么最小时间、最大时间、主题定制,概不在本插件功能范围。

保留必要的依赖

本插件虽说是基于zepto,实际上还隐性依赖了Github上面一个比较牛的库fastclick。我们知道,移动端点击事件处理有两个常见的问题:(1)移动端click事件有300ms,通常采用touch事件来代替click事件来提高灵敏性;(2)touch事件会存在穿透的问题,一般插件都不用touch事件;基于这两个问题,fastclick做了兼容,只需要简单调用它提供的api就能够愉快得和原本一样调用click事件,所以这个依赖不能省。至于依赖zepto,实际上是可有可无的,一来博主平时工作都是写原生js的,不用插件也没多大的感觉,二来插件受众面就会小一些。不过鉴于zepto在移动端已然和zepto在PC端一样如鱼得水,就毫不客气采用了。

既能够支持模块化又能本地引用文件使用的

久远一点的插件基本都是让你下载一个文件,然后用script去引用,这样本无可厚非,只不过放着最大的包管理器npm不用,岂不是对不起页面仔这个称号。所以本插件支持文件引用也支持CMD方式的模块引用。

功能介绍

直接上图:

基于zepto的移动端轻量级日期插件--date_picker

技术细节

transitionEnd事件

插件的主面板是当前月份的天数详情,如果点击上一个月或者下一个月插件需要计算出上一个月或者下一个月的天数信息,然后插入到DOM节点中。在插入到DOM节点之后,就需要采用动画效果来显示最新的一月并且褪去老的一个月,采用的方式是CSS2d转化加过渡。我们需要处理的就是在旧的一个月褪去看不见的时候及时从DOM树中删除,不然如果用户一直点下一个月或者上一个月的话,内存会炸的。为了实现这个移除功能,一个办法是采用setTimeout事件在特定的时间去删除节点,经过尝试,发现由于Javascript定时器不准确的特性和前后一个月切换带来的逻辑复杂度增加,这种方案很不可行。
于是,本插件采用了第二个方案:transitionEnd事件。直接引用一下MDN的介绍:

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.

也就是只要你不去随便乱动元素的CSS属性,在动画完成的时候,你就可以执行相应的操作(删除节点)。
再来看看兼容性:

基于zepto的移动端轻量级日期插件--date_picker

对于移动Web开发足矣!

最后就是在绑定事件的兼容性问题,不同厂商对于这个事件的定义并不一致,比如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;
 }

安装使用

安装

支持下面两种方式

  1. git clone之后直接拷贝引用bin文件夹下面的datepicker.min.css和datepicker.min.js
  2. 从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: open和close,其中特别注意上面demo中_date在获取焦点之后里面强制去除了焦点,是为了避免安卓下面为input标签设置readonly属性并不能禁止原生键盘弹出的问题。

Javascript 相关文章推荐
javascript 写类方式之四
Jul 05 Javascript
HTML长文本截取含有HTML代码同样适用的两种方法
Jul 31 Javascript
你可能不知道的JavaScript的new Function()方法
Apr 17 Javascript
JQuery实现当鼠标停留在某区域3秒后自动执行
Sep 09 Javascript
jQuery中的编程范式详解
Dec 15 Javascript
javascript+html5实现绘制圆环的方法
Jul 28 Javascript
什么是JavaScript中的结果值?
Oct 08 Javascript
jQuery中DOM节点删除之empty与remove
Jan 20 Javascript
jquery+css实现侧边导航栏效果
Jun 12 jQuery
Vue-CLI 3.X 部署项目至生产服务器的方法
Mar 22 Javascript
vue实现修改图片后实时更新
Nov 14 Javascript
使用纯前端JavaScript实现Excel导入导出方法过程详解
Aug 07 Javascript
基于Javascript实现二级联动菜单效果
Mar 04 #Javascript
jquery ajax双击div可直接修改div中的内容
Mar 04 #Javascript
js实现文字滚动效果
Mar 03 #Javascript
JavaScript使ifram跨域相互访问及与PHP通信的实例
Mar 03 #Javascript
JQuery日期插件datepicker的使用方法
Mar 03 #Javascript
jQuery日历插件datepicker用法详解
Mar 03 #Javascript
初步使用Node连接Mysql数据库
Mar 03 #Javascript
You might like
浅析php变量修饰符static的使用
2013/06/28 PHP
php str_getcsv把字符串解析为数组的实现方法
2017/04/05 PHP
PHP+Oracle本地开发环境搭建方法详解
2019/04/01 PHP
PHP的图像处理实例小结【文字水印、图片水印、压缩图像等】
2019/12/20 PHP
javascript Demo模态窗口
2009/12/06 Javascript
iframe子父页面调用js函数示例
2013/11/07 Javascript
经过绑定元素时会多次触发mouseover和mouseout事件
2014/02/28 Javascript
Jquery easyUI 更新行示例
2014/03/06 Javascript
jQuery中innerWidth()方法用法实例
2015/01/19 Javascript
JS的数组迭代方法
2015/02/05 Javascript
JS+CSS实现模仿浏览器网页字符查找功能的方法
2015/02/26 Javascript
详解AngularJS如何实现跨域请求
2016/08/22 Javascript
微信小程序之仿微信漂流瓶实例
2016/12/09 Javascript
jQuery实现的粘性滚动导航栏效果实例【附源码下载】
2017/10/19 jQuery
微信小程序实现获取小程序码和二维码java接口开发
2019/03/29 Javascript
全面了解JavaScript的作用域链
2019/04/03 Javascript
微信小程序收货地址API兼容低版本解决方法
2019/05/18 Javascript
在Vue中使用this.$store或者是$route一直报错的解决
2019/11/08 Javascript
vue打开子组件弹窗都刷新功能的实现
2020/09/21 Javascript
[03:04]DOTA2英雄基础教程 影魔
2013/12/11 DOTA
[42:11]TNC vs Pain 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/20 DOTA
python模拟登录百度代码分享(获取百度贴吧等级)
2013/12/27 Python
Python访问MySQL封装的常用类实例
2014/11/11 Python
Python实现在线音乐播放器
2017/03/03 Python
python嵌套字典比较值与取值的实现示例
2017/11/03 Python
轻松实现TensorFlow微信跳一跳的AI
2018/01/05 Python
python斐波那契数列的计算方法
2018/09/27 Python
Python数据报表之Excel操作模块用法分析
2019/03/11 Python
Python collections模块使用方法详解
2019/08/28 Python
python实现文法左递归的消除方法
2020/05/22 Python
python如何处理程序无法打开
2020/06/16 Python
瑞典领先的汽车零部件网上零售商:bildelaronline24.se
2017/01/12 全球购物
Huda Beauty官方商店:化妆和美容产品
2020/09/05 全球购物
军神教学反思
2014/02/04 职场文书
《夸父追日》教学反思
2014/02/26 职场文书
使用GO语言实现Mysql数据库CURD的简单示例
2021/08/07 Golang