背景
最近开发移动端项目用到了iscroll,踩了不少坑,因此阅读源码加深下对这个工具的了解。
本次阅读的是iscroll-lite,包含了主要的功能,比完整版少了鼠标滚轮,滚动后对齐到特定位置,按键绑定及定制滚动条等功能。
主体结构
以当前的5.2版本为例,前三百行是工具函数,封装了一些工具。三百行到四百行是构造函数IScroll,起到配置和初始化的效果。四百行到一千修改了IScroll的原型,给IScroll实例加上了各种方法。最后是模块化相关的判断。总体的结构是很清晰的。
工具函数
_prefixStyle
用于浏览器兼容。
|
|
能力检测
判断浏览器是否支持相关的特性
|
|
还有一些事件监听方面的处理函数,处理class的函数,处理惯性的函数momentum
父元素的位置
|
|
对事件进行分类
|
|
动画处理的函数
|
|
tap和click的事件模拟
|
|
touchAction的设定
|
|
元素的位置
|
|
构造函数
先是获取了wrapper和scroller,接着是一些能力检测。
在这里通过eventPassthrough,scrollY,scrollX,freeScroll来配置滚动的方向。只有scrollY是默认为true,其他都是未设定undefined.
当eventPassthrough的值为vertical时,在垂直方向不使用iscroll的滚动,使用原生的滚动。为horizontal时,则水平方向如此。想要二维自由滚动,不能设置该值。
接着还有其他属性的设定,最后调用_init,refresh,scrollTo,enable等函数
一些原形上绑定的函数
_init
只调用了_initEvents函数
_initEvents
在这里根据配置给wrapper或是window加入了鼠标事件,pointer事件和触摸事件,transition事件等事件的监听。这里用到了一种少见的事件绑定方法,在这里事件绑定的第三个参数不是常见的function,而是iscroll对象。而iscroll对象里有一个方法handleEvent,这种方式的好处就是可以传递this
refresh
保存wrapper和scroller的尺寸信息,及wrapper的位置信息。设定最大滚动距离,为负数。
接着判断是否存在水平滚动或是垂直滚动
如果浏览器支持pointer,使用touchAction来限制wrapper。
最后调用resetPosition函数来判断是否需要重置位置
_start
保存事件的类型,如果跟已经保存的事件类型不是同一类,不继续执行函数。
如果scroller在滚动状态,调用getComputedPosition函数来获取scroller的位置,调用_translate方法让scroller停在当前位置。
保存当前的位置信息和触发事件的位置信息,设置状态信息
|
|
_move
获取事件的位置信息,对比_start中保存的位置信息,计算偏移值
保存新的位置信息,位移信息
如果偏移小于10像素不执行滚动。偏移的大小值和设定来根据判断滚动的方向。最后调用_translate函数来滚动
_translate
根据设定,修改滚动条中的transform的值或是修改left和top的值来进行具体的滚动,保存信息到this.x和this.y
|
|
_end
让scroller滚动到整数位置,根据位移和触发事件的时间的情况,摸你tap事件、click事件或是执行flick事件或调用scrollTO函数进行惯性滚动。
scrollTo
主要是选择动画效果,调用__translate或是_animate来进行滚动
_animate
根据所选的动画效果,在每一个requestAnimationFrame下调用_translate函数