js实现类似ios省市区三级联动选择器

1. 没有标题的标题

某天,我们公司有个需求里面有一块需要做一个省市区三级联动的选择器(手机端),我内心想:简单呀,网上找个demo一套就行了吖,然后美滋滋下班!!但是发现网上并没有适用的手机端三级联动选择器!宝宝好委屈,但宝宝不说!

但仔细想想,网上没有好的,那我可以模范ios的三级联动自己写呀,写的好的话还可以装比卖萌呀,咳咳!不是,仔细想了一下,人生的意义在于什么?在于折腾!!!生命的意义在于什么,在于创造呀!!!在一瞬间像我这么才华横溢的人就应该不走寻常路!!! 你们说对不对!!掌声在哪里?

趁着这三分钟的热度还没消散,果断撸起了代码。但是三分钟过后!好难呀,这么写呀,ios的效果好顺畅,好牛逼呀,感觉是用了什么牛逼算法呀,我不懂算法,怎么办!!!

其实ios的三级联动在我看来跟iscroll这个库的效果是一致的,之前我曾经看过iscroll的源码,自己重新写了一个类似简单的iscroll的库,100行左右的代码,毕竟知识的搬运工是很勤奋的!

iscroll的库里面只有一个核心算法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
function momentum(current, start, time, lowerMargin, wrapperSize, deceleration) {
//当前位置 current
//开始位置 start
//经历时间 time
//最大滚动长度 lowerMargin
//屏幕高度 wrapperSize

var distance = current - start,
speed = Math.abs(distance) / time,
destination,
duration;

deceleration = deceleration === undefined ? 0.0006 : deceleration; //加速度a

// s = at*t/2 t = v/a s = v*v/2*a
destination = current + ( speed * speed ) / ( 2 * deceleration ) * ( distance < 0 ? -1 : 1 );

duration = speed / deceleration;

if ( destination < lowerMargin ) {
destination = wrapperSize ? lowerMargin - ( wrapperSize / 2.5 * ( speed / 8 ) ) : lowerMargin;
distance = Math.abs(destination - current);
duration = distance / speed;
} else if ( destination > 0 ) {
destination = wrapperSize ? wrapperSize / 2.5 * ( speed / 8 ) : 0;
distance = Math.abs(current) + destination;
duration = distance / speed;
}

return {
destination: Math.round(destination),
duration: duration
};
};

这应该是匀减速运动的基本公式(由s=atxt/2,t=v/a得出s=vxv/2xa), 知识搬运工就是强大呀!最后基于自己简易版的iscroll,实现了三级联动选择器
demo代码 https://codepen.io/yuanxiaosi/pen/KjdQbd ( 请使用手机调试模式, 体验更加流畅哦 )
哇,狂拽酷炫吊炸天!掌声不绝!

因为项目代码是react,我只是基于react写了一个小组件,
1.style标签里面是主要样式

2.引入的select-iscroll.js是核心js库,用new初始化组件,还有获取当前位置和设置当前位置的方法getIndex和setIndex

3.html里面内嵌的js是联动的业务js了

其实我可以写成原生js版的,但是业务繁忙,懒得倒弄,而且我们公司的人大都是reacter,我自己写react也写习惯了, 嘿嘿,人有惰性,难以自已,但仍希望自己不忘初心,粪发图强!我提供的是思路,如果对demo代码意见或者建议,可以自己改进!不用来找我!