基于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 相关文章推荐
EXTJS FORM HIDDEN TEXTFIELD 赋值 使用value不好用的问题
Apr 16 Javascript
jquery获取特定name所有选中的checkbox,支持IE9标准模式
Mar 18 Javascript
用js调用迅雷下载代码的二种方法
Apr 15 Javascript
JavaScript编程中容易出BUG的几点小知识
Jan 31 Javascript
bootstrap datepicker限定可选时间范围实现方法
Sep 28 Javascript
使用纯JS代码判断字符串中有多少汉字的实现方法(超简单实用)
Nov 12 Javascript
JQuery异步提交表单与文件上传功能示例
Jan 12 Javascript
input file样式修改以及图片预览删除功能详细概括(推荐)
Aug 17 Javascript
JS中实现隐藏部分姓名或者电话号码的代码
Jul 17 Javascript
vue实现在线翻译功能
Sep 27 Javascript
解决Vue使用bus总线时,第一次路由跳转时数据没成功传递问题
Jul 28 Javascript
JavaScript offset实现鼠标坐标获取和窗口内模块拖动
May 30 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超全局数组(Superglobals)介绍
2015/07/01 PHP
PHP中Array相关函数简介
2016/07/03 PHP
php从数据库中读取特定的行(实例)
2017/06/02 PHP
laravel5使用freetds连接sql server的方法
2018/12/07 PHP
Laravel 自定命令以及生成文件的例子
2019/10/23 PHP
js实现在页面上弹出蒙板技巧简单实用
2013/04/16 Javascript
用nodejs实现PHP的print_r函数代码
2014/03/14 NodeJs
JS获取客户端IP地址、MAC和主机名的7个方法汇总
2014/07/21 Javascript
JS动态修改iframe高度和宽度的方法
2015/04/01 Javascript
jQuery使用drag效果实现自由拖拽div
2015/06/11 Javascript
JS两个数组比较,删除重复值的巧妙方法(推荐)
2016/06/03 Javascript
微信小程序 Nginx环境配置详细介绍
2017/02/14 Javascript
JavaScript评论点赞功能的实现方法
2017/03/13 Javascript
细说webpack源码之compile流程-rules参数处理技巧(2)
2017/12/26 Javascript
nodejs使用redis作为缓存介质实现的封装缓存类示例
2018/02/07 NodeJs
VUE2.0中Jsonp的使用方法
2018/05/22 Javascript
Canvas实现微信红包照片效果
2018/08/21 Javascript
详解es6新增数组方法简便了哪些操作
2019/05/09 Javascript
微信小程序实现单个卡片左滑显示按钮并防止上下滑动干扰功能
2019/12/06 Javascript
Python 执行字符串表达式函数(eval exec execfile)
2014/08/11 Python
Python3生成手写体数字方法
2018/01/30 Python
Python中max函数用于二维列表的实例
2018/04/03 Python
对python内置map和six.moves.map的区别详解
2018/12/19 Python
Python设计模式之简单工厂模式实例详解
2019/01/22 Python
django的分页器Paginator 从django中导入类
2019/07/25 Python
python tkinter组件摆放方式详解
2019/09/16 Python
python3中sorted函数里cmp参数改变详解
2020/03/12 Python
沙龙级头发造型工具:FOXYBAE
2018/07/01 全球购物
美国折衷生活方式品牌:Robert Graham
2018/07/13 全球购物
Coggles美国/加拿大:高级国际时装零售商
2018/10/23 全球购物
Lancer Skincare官方网站:抗衰老皮肤护理
2020/11/20 全球购物
Levi’s西班牙官方网站:李维斯,著名的牛仔裤品牌
2020/08/20 全球购物
黄金酒广告词
2014/03/21 职场文书
写求职信有哪些注意事项
2014/05/08 职场文书
学校欢迎标语
2014/06/18 职场文书
实习协议书
2015/01/27 职场文书