写在前面的话,以手机浏览的朋友,因手机屏幕不是很宽,如果存在代码看不全的情况,所有的代码区是可以左右滑动的,当然,你也可以点击代码区右上角从左往右数的第二个按钮,让代码换行显示。

之前做一个门户型的手机网站,要做一个类似今日头条那种可以拖动的导航,就是看上去像是手机原生拖动网页上下滚动的那种效果,拖得快,滚得快,拖得慢,滚得慢,放开手指后还要有一定的缓冲距离。由于之前做手机页面都是用的简单的click事件,没用到拖动,所以刚开始的时候也遇到了很多问题,因为手机端没有什么mousedown,mousemove,mouseup等事件,取而代之的是touchstart,touchmove,touchend,但问题时手机上屏幕上可以同时放多个手指,所以touch事件和mouse事件肯定有不一样的地方,我也是到处找资料,看了很久才勉强会用。由于今天的重点是滑动导航,touch的事就先不说了,有兴趣的同志可以看一下这篇文章,浅谈javascript的Touch事件

 

下面进入今天的主题,navscroll。首先,在代码实现之前,我们先弄明白它的原理是什么,只有原理搞清楚了,我们代码实现起来才会流畅,理解起来也会懂得更快。其实它的原理就跟幻灯片是一回事,先定义一个外层盒子,超出部分隐藏,position设置为相对定位,然后再在里面添加内容,设置绝对定位,动态改变里面的left值,就能实现其效果。我们以图说明:

最外层盒子宽度为400,里面可以滚动的内容宽度为1000,则可以滚动的最大距离,我们设为maxLeft,它等于1000-400=600。当导航滚到最右边时,它的left值则为-600px,如下图所示:

针对现在的移动设备,浏览器几乎全兼容css3,所以我们在真正实现的时候,也可以用translateX来代替left。我这里就只介绍改变left的方式了,喜欢的朋友可以自己尝试一下translateX的做法。

 

接下来,我们再来看一下怎么判断拖动的快慢。其实道理也很简单,就像我们跑步一样,比如第一分钟你在100米的位置,第二分钟你在400米的位置,那你这一分钟的速度就是400-100=300米/分钟,而第三分钟时,你的位置在800米的位置,那么第二分钟到第三分钟你的速度就是800-400=400米/分钟,说明你是越来越快了。我们的拖动也是一样,假设第一次监听到拖动时手指的位置在90px(图中1)处,而第二次监听到拖动时手指的位置在180px(图中2)处,那么你的速度就是90px/次拖动。如下所示:

 

然后,我们再来考虑如何让导航在手指放开后还能缓慢移动一段距离。这个就跟我们踢足球一样,球踢出去之后,由于受到地面的摩擦,它的速度会越来越小,越来越小,最终变为0。所以,当我们放开手指后,也要让拖动的元素的速度越来越小,但手机上的这些东西并没有所谓的什么摩擦力,我们唯一能采用的办法就是每次都让它的速度乘以一个小于1的数,但又必须大于0,因为乘以0就为0了,千万别整个小于0的数啊,不然到时候它就要往反方向跑了。我们一般叫这个数为摩擦系数,我们假设刚开始的速度为100,摩擦系数为0.9,那么速度依次为100*0.9=90,90*0.9=81,81*0.9=72.9,72.9*0.9=65.61………,这样一直下去,但这样它永远不会等于0,为此,我们可以规定,当速度小于某一个值的时候,就把它视为0,不动了。

 

最主要的几个点已经讲完了,再简单的说两个技巧上的东西:

1、我们的导航元素有可能并不是固定的,可能有10个栏目,也有可能有20个栏目,但是对于ul里面的li元素,我们又必须设置float为left才会并排,如果不给ul一个合适的宽度,装不下的它会自动往下挤,但我们ul的宽度写死了又不好,解决办法是把ul的display设置为table-cell,再把里面的li的display设置为inline-block,但inline-block的元素默认有一点间距,可以通过把ul的font-size设置为0来清除,不过这样的话必须重写li里面的font-size。

2、导航放到页面上之后,我们可能会实时编辑导航,增加和删除,那么ul的宽度就随时可能会变,处理办法是在每次touchstart的时候都重新获取ul的宽度。

剩下的还有一些细节上的东西,我就不再一一说明了,看代码就行。作为一个前端功底不是怎么样的人来说,代码肯定是还有些问题的,希望大家指正,如果你有更好的方案,欢迎分享。

下面直接上代码

页面html

js文件simulateTouchScroll.js

上面的代码没加注释,如果需要看注释的朋友,请移步本代码git,自行下载查看,git另附压缩版,地址https://github.com/veznlee/simplePlugin