前段时间在搞移动终端(移动web)的项目,其中需要用到滚动的功能(html的滚动效果不好,且在低版本上不支持)。后面上网找了下资料,发现大部分人都在用iscroll4(下面简称v4),下载下来试了下确实不错。在PC上滚动效果确定很好,在整合到移动web中,在部分机型(或者部分系统版本)上有卡顿,不是很流畅,有可能是配置低,也有可能某些属性设置错误造成滑动不顺畅。后面又上网查找资料,发现了iscroll5(下面简称v5)的测试版本(bate5.0.1)已经出来,果断下载下来耍耍(地址:http://cubiq.org/iscroll-5-ready-for-beta-test)
不过v5和v4差距也是有点大,对于想升级到v5的朋友们,可能要花点时间看源码做相应的升级调整(因为官方还未有相关文档出来),今天笔者借着使用过的一些功能的升级调整方式和注意点大概说明下(笔者没有去看全部的源码,只是将之前iscroll4用到的功能做相应调整),废话不多说,开始!
1、 首先是iscroll的实例化方式
v4 var scroller = new iScroll('id'); v5 var scroller = new IScroll('#id');
i改成大写了,应该是为了规范写法。后面的目标由原来的只能是DOM对象或者id改成可以支持DOM对象和选择器选择,源码中的选择方式是document.querySelector(el),而不再是document.getElementById(el);
2 、v5不再对目标添加overflow:hidden,用户有需求可以自行添加
3、v5的事件也不再是在option里面写了,而是仿造jquery的on绑定事件的方式。
1 v4 2 var scroller = new iScroll('id',{ 3 scrollStart : function(){ 4 onsole.log('scroll started'); 5 } 6 }); 7 8 v5 9 var scroller = new IScroll('#id'); 10 scroller.on('scrollStart', function () { console.log('scroll started'); });
4、v4中获取当前页的索引什么的是通过this.currPageX或者this.currPageY,而v5则是放在this.currentPage中,如要获取水平当前页的索引this.currentPage.pageX;
v4中滚动到某一页的事件调用是scrollToPage(x,y,time) ,而v5中则是gotoPage(x,y,time,easing);easing 为v5中新加的滚动到边界时的反应特效,这里不细说,大家可以自己尝试看看,注意:若添加了特效,scrollEnd事件不会触发(测试版本可能没有添加支持,笔者已经留言给iscroll作者),如在v4中有实现上拉加载更多等事件,则无法添加特效,否则你会发现上拉加载更多的逻辑不会执行。
5、v5测试版中的事件比较少,很多事件都还没添加,如v4中的scrollMove也没有,由于项目需要,我暂时在源码中_move函数的最后面添加了支持
6、v5默认水平滚动禁用掉,竖直默认启用,而v4中则是默认都启用。
7、V4中可通过设置option的以下参数来控制当滚动时出现滚动条,滚动结束则隐藏滚动条,v5无法实现(实际上很多option都不一样了,或者说根本没有支持了,也许以后会慢慢的添加,毕竟现在只是测试版本)
fixedScrollbar : true, hideScrollbar : true,
目前可以通过以下代码来暂时实现
1 var iSObj = new IScroll(obj,opt); 2 3 //滚动条在滚动时显示出来,滚动结束隐藏 4 iSObj.on("scrollEnd",function(){ 5 if(this.indicator1){ 6 this.indicator1.indicatorStyle['transition-duration'] = '350ms'; 7 this.indicator1.indicatorStyle['opacity'] = '0'; 8 } 9 }); 10 iSObj.on("scrollMove",function(){ 11 if(this.indicator1){ 12 this.indicator1.indicatorStyle['transition-duration'] = '0ms'; 13 this.indicator1.indicatorStyle['opacity'] = '0.8'; 14 } 15 });
8、v4默认若内容不超过显示区域,则不会出现滚动条,就算手指过去滚动,也不会有任何反应,就算你设置了滚动条默认显示,他也不会出现滚动条。v4中就算内容比较少,但是你去滚动,还是会有到边界反弹回来的效果,而且若有开启滚动条,滚动条也会显示。
-------------------------------------------------------------------------------------------------------------
9、v5.0.4目前还未提供下拉刷新和上拉加载的demo,上拉加载和v4的demo类似,下拉需要临时方案解决(改源码)
1)、options中加一个属性 topOffset : 0
2)、resetPostion方法中的
if ( x == this.x && y == this.y ) { return false; }
前面加上
1 y = this.y >= this.minScrollY || this.maxScrollY > 0 ? this.minScrollY : this.y < this.maxScrollY ? this.maxScrollY : this.y;
3)、refresh中的
1 var rf = this.wrapper.offsetHeight; // Force reflow 2 3 this.wrapperWidth = this.wrapper.clientWidth; 4 this.wrapperHeight = this.wrapper.clientHeight; 5 6 //add 7 this.minScrollY = -this.options.topOffset || 0; 8 //end add 9 /* REPLACE START: refresh */ 10 11 this.scrollerWidth = this.scroller.offsetWidth; 12 13 //mdy 14 //this.scrollerHeight = this.scroller.offsetHeight 15 this.scrollerHeight = this.scroller.offsetHeight+ this.minScrollY; 16 //end mdy 17 /* REPLACE END: refresh */ 18 19 this.maxScrollX = this.wrapperWidth - this.scrollerWidth; 20 21 //mdy 22 //this.maxScrollY = this.wrapperHeight - this.scrollerHeight; 23 this.maxScrollY = this.wrapperHeight - this.scrollerHeight+ this.minScrollY; 24 //end mdy 25 .................. 26 .................. 27 ..................
10、v4中如果既要上下又要左右滚动,可考虑双层嵌套,但是一般 不建议双层嵌套,体验不是很好,会有蛮多问题,尽量去避免这种需求,做到一个方向的滚动即可。如果实在是需要也不是很大问题。v4一个很大的问题是若用双层嵌套,用户在滑动时若稍微有点斜着滑就会造成整块滑动区域都飘起来了(也就是说他即在做左右滑动又在做上下滑动,但实际上我们的需求是用户同一时间只能是某一个方向滑动)v5.0.1版本有解决了这个问题,v5.0.4又有这个问题了(不知道作者什么想法),可以通过修改源码的临时方案解决.但是此种方案只能解决在用户一开始按住滑动只有一个方向,哪怕一像素,这时候不管你如果滑动,都会保证只有一个方向可以滑动(我们需要的),而如果用户一开始按住滑动是直接45度斜角滑的 ,那么此问题还是存在。
1 _move: function (e) { 2 if ( !this.enabled || utils.eventType[e.type] !== this.initiated ) { 3 return; 4 } 5 6 if ( this.options.preventDefault ) { // increases performance on Android? TODO: check! 7 e.preventDefault(); 8 } 9 10 var point = e.touches ? e.touches[0] : e, 11 12 //mdy 13 //这2句必须换成下面那2句,否则当多层嵌套(即有上下滚动又有左右滚动)时会变成一边左右滚一边上下滚,但实际上我们只需要专注某一个方向 14 //deltaX = this.hasHorizontalScroll ? point.pageX - this.pointX : 0, 15 //deltaY = this.hasVerticalScroll ? point.pageY - this.pointY : 0, 16 deltaX = point.pageX - this.pointX, 17 deltaY = point.pageY - this.pointY, 18 19 //end mdy 20 timestamp = utils.getTime(), 21 newX, newY, 22 absDistX, absDistY; 23 24 this.pointX = point.pageX; 25 this.pointY = point.pageY; 26 ............................. 27 ............................. 28 .............................
11、若遇到在滚动区域中某些地方的默认事件无法触发(如A标签的链接),基本上是由于IScroll把滚动区域中的表单元素默认事件都禁用掉了,也就是e.preventDefault()(为了滚动顺畅),可根据需要在源码中做个判断,比如你想保留A标签的默认事件,则可以对被点击的元素的tagName进行判断,然后决定要不要e.preventDefault()。
完整demo下载地址:http://download.csdn.net/detail/gcz564539969/6901753