iScroll5是在iScroll4的基础重构而来,使用时发现网上大部分例子都是基于iScroll4,在iScroll5上面并不适用,比如横向滚动、当前索引、元素对齐等,这些不在赘述,有需求可以考虑去看看源码(重构过的源码看起来清爽很多)。
因为自己需要一个卡片左右滑动的效果,同时还希望有边界对齐的能力,不清楚这个效果有没有类似实现,大概看了下,新版iScroll也不是很大,就直接拿来用了,效果如下图所示:
边界始终是在上面时间导航始终不会停留在文字中间,下面卡片始终只会停留在元素左侧边界,不会出现如下图所示情况:
基本效果很简单,因为不想重复造轮子,直接拿iScroll5来实现,时间导航部分还好,使用iScroll5,事先计算好要滚动元素的父级宽度,子元素直接float,然后实例化iScroll设置横向滚动和元素对齐即可,代码如下:
new IScroll('#wrapper', { scrollX: true, snap: '.item' });
下面的卡片就有些麻烦了,因为是动态加载,期初考虑使用iscroll-infinite.js版的缓存功能(updateCache)实现(iScroll5有五个版本,分别为iscroll.js、iscroll-infinite.js、iscroll-lite.js、iscroll-probe.js、iscroll-zoom.js),尝试后发现iscroll-infinite.js只实现了纵向的缓存刷新,如果设置scrollX为true,就会出现很严重的错位,粗略看了一下,这个改起来有点麻烦,最后只好放弃使用此功能,认为操作dom后调用iscroll对象的refresh方法,结果发现开启了snap的情况下,当前索引定位会出现越界而报错,因为snap默认支持传boolean或者字符串selector,传boolean值为true的情况,操作没有出错,但是组件根据容器宽度进行对齐,明显不符合我们的需求;而传入selector的情况下,第一次初始化时候调用了_initSnap,通过this.options.snap查找到所有dom并缓存在this.options.snap,而调用refresh时并没有刷新this.options.snap的值,故而这里做了简单改动,具体代码片段如下
找到_initSnap方法
_initSnap: function () { this.currentPage = {}; if ( typeof this.options.snap == 'string' ) { this.options.snap = this.scroller.querySelectorAll(this.options.snap); } this.on('refresh', function () { //... this.pages = []; //... }); this.on('flick', function () { //... }); }
改为
_initSnap: function () { this.currentPage = {}; if (typeof this.options.snap == 'string') { this.options.snapSelector = this.options.snap; this.options.snap = this.scroller.querySelectorAll(this.options.snap); } this.on('refresh', function () { //... this.pages = []; if (this.options.snapSelector) { this.options.snap = this.scroller.querySelectorAll(this.options.snapSelector); } //... }); this.on('flick', function () { //... }); }
将配置为selector的this.options.snap属性先保留到snapSelector,然后通过this.options.snap查找元素列表并缓存,在refresh时,使用snapSelector重新查找元素列表并替换。以上“//…”表示省略部分代码,仅所示例,具体代码位置请根据所使用的版本判断(注:lite版不支持元素对齐功能)。
上一篇: 安卓Adapter中getView方法重复执行及索引错位问题解决 下一篇: sudo * 提示 command not found 解决