以前写了一篇 MultiPicker -『为移动端而生』的自定义多级联动选择器,获得了不少人的关注。鉴于不少人对这种手写插件的过程很好奇,因此写了几篇文章,来讲说它的成长史~git
在阅读本文以前,确保你有稍微看过 MultiPicker 的源码 喔~github
点击查看源码 ,也能够在 npm 上找到他们:算法
回顾上集:如何造一个移动端的联动选择器(一)segmentfault
实现弹层的思路:【插入DOM → 初始化联动的数据 → 绑定事件 】数组
① 在插入DOM的部分( initDomFuc ),采用字符串拼接的方式插入DOM(而不是使用字符串模板)。框架
联动的主要结构式以下图:dom
每一个联动是一个 div,div 包裹着一个 ul,ul 中的每一个 li 就是联动的值函数
其中div的高度是5个 li 的高度,ul的高度是实际的全部 li 的高度。
② 在初始化联动数据的部分( initReady ),在头尾分别插入两个空字符,可以起到占位符的做用,这样在计算手势的translate3d的时候更方便。
③ 为DOM元素绑定事件时,具体作法有两步:
第一步:为每一个初始化好的ul绑定touch事件( initReady );
第二步:为一些操做按钮绑定事件( initBinding )。
③ - 第一步:touch事件的种类无非就是 touchstart、touchmove 和 touchend。但须要在每次滑动的时候记录一些数据。这是为了实现一个滑动加速度的效果,下文会说到。
③ - 第二步:用到了本身封装的一个简单的事件监听函数on:
这个函数主要用在【触发】【取消】和【提交】这几个重要按钮上。
PS:在设计样式的过程当中考虑到,完整使用【年月日时分】
五种时间单位的场景居多,为了优化界面和用户体验,因此在日期选择器的设计中,须要设计一种带tab切换
效果的完整版日期选择器。其余场景中不会出现。
我发现,不管用户使用哪一个手指,只要用户的滑动弧长在短期内比较大的话,说明用户比较想快速向上滑或是向下滑。好比,在选择出生年份的时候,用户确定会想快速滑到上面的部分,就会用很快速的手势向下滑动一个比较大的弧长。这时候就应该有一个滑动加速度的效果。
那么如何实现呢,如何判断用户想要快速滑动呢?
很简单,只须要考虑,单位时间内的速度变化率,也就是加速度,就好了。
以前提到过,在touchmove的过程当中会有一个 【speed数组】用来存储滑动时,手势的速度。
并在touchend中调用 initSpeed 函数,肯定最后 transition-duration
的值。
initSpeed 的主要工做是计算 speed 中的速度方差,方差和加速度是成正相关的。
因此当方差大于0.1时,ul 的实际滑动距离是手势滑动距离的两倍,transition-duration的值为0.2s;
而当方差小于0.1的时候,就认为基本是匀速滑动,ul 的实际滑动距等于手势滑动距离,取 speed[0] 做为 transition-duration 的值。
肯定好了滑动距离以后,就能够计算最后停留的位置 translate3d ( initPosition )。
滑动加速度的效果就基本实现了。
Github地址:『为移动端而生』的自定义多级联动选择器
到此,dom的操做和手势算法就已经基本掌握了。
预知后话,后两天见分晓
我是嘉宝Appian,一个卖萌出家的算法妹纸。