之前在webkit上开发一个滚动控件,需要完成的是一段文字,上下键可以滚动,且自定义滚动条。第一想法就是浏览器原生overflow:scroll,且webkit支持自定义滚动条样式:
webkit自定义滚动条样式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
/*定义滚动条高宽及背景 高宽分别对应横竖滚动条的尺寸*/ ::-webkit-scrollbar { width: 0.05rem; height:1rem; background-color: transparent; } /*定义滚动条轨道 内阴影+圆角*/ ::-webkit-scrollbar-track { background-color: transparent; } /*定义滑块 内阴影+圆角*/ ::-webkit-scrollbar-thumb { border-radius: 0.1rem; /*-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.3);*/ background-color: rgba(255,255,255,0.6); } |
后来换了个引擎,发现其他引擎不支持自定义滚动条,那就满足不了UED的要求了。来同事推荐使用IScroll,用了一下,确实比较方便,与平台无关,可操作的属性还有性能都很理想,记录一下:
首先看官方文档 https://iiunknown.gitbooks.io/iscroll-5-api-cn/content/versions.html
github地址:https://github.com/cubiq/iscroll
demo:http://cubiq.org/dropbox/iscroll4/examples/simple/
直接拿demo中的iscroll.js套到自己的工程上,一个段落就是一个li,new 一下就完事了,滚动拖动也很happy。然后发现,我按上下方向键没有响应。
IScroll按键事件绑定:
查源码看iscroll的事件处理,都在handleEvent函数里面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
handleEvent: function (e) { var that = this; switch(e.type) { case START_EV: if (!hasTouch && e.button !== 0) return; that._start(e); break; case MOVE_EV: that._move(e); break; case END_EV: case CANCEL_EV: that._end(e); break; case RESIZE_EV: that._resize(); break; case WHEEL_EV: that._wheel(e); break; case 'mouseout': that._mouseout(e); break; case TRNEND_EV: that._transitionEnd(e); break; } } |
根本就没有keyEvent,看来偷懒是不行的,官方文档看一下,原来iscroll有5个版本,各自平台都是不一样的,demo中这个估计是移动平台用的iscroll-lite版本,移动平台根本不鸟方向键的。
去github上down下来源码,找了找,build目录下,5个版本都有。用最原始的common版本,这个版本的handleEvent就丰富多了:
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 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
handleEvent: function (e) { switch ( e.type ) { case 'touchstart': case 'pointerdown': case 'MSPointerDown': case 'mousedown': this._start(e); break; case 'touchmove': case 'pointermove': case 'MSPointerMove': case 'mousemove': this._move(e); break; case 'touchend': case 'pointerup': case 'MSPointerUp': case 'mouseup': case 'touchcancel': case 'pointercancel': case 'MSPointerCancel': case 'mousecancel': this._end(e); break; case 'orientationchange': case 'resize': this._resize(); break; case 'transitionend': case 'webkitTransitionEnd': case 'oTransitionEnd': case 'MSTransitionEnd': this._transitionEnd(e); break; case 'wheel': case 'DOMMouseScroll': case 'mousewheel': this._wheel(e); break; case 'keydown': this._key(e); break; case 'click': if ( !e._constructed ) { e.preventDefault(); e.stopPropagation(); } break; } } |
然后套用上去,可以支持方向键了。中间遇到两个小问题,第一个是按键一直没反应,检查下是z-index太小,keyEvent被上层元素拿走了;第二个是只有在#warpper拿到focus的时候才响应按键,但我用的引擎不支持focus,这个也不难,页面强行绑定handleEvent:
1 2 3 4 5 6 |
document.addEventListener("keydown", function(evt) { if (evt.keyCode === keyCodes.ENTER) { } else { myScroll && myScroll.handleEvent(evt); } }, false); |
然后整个页面随便按什么键,都可以响应了。接下来就是滚动条样式的问题了,这个也简单,跟着官方文档&样例走就行
http://lab.cubiq.org/iscroll5/demos/styled-scrollbars/
关键步骤有三个:
1.option
1 2 3 4 5 |
myScroll = new IScroll(document.getElementById('wrapper'), { keyBindings: true, // 绑定按键事件 scrollbars: 'custom', // 自定义样式 resizeScrollbars: false // 是否自动缩放滚动条 }); |
设置了scrollbars: 'custom',在页面的Elements就可以找到
<div class="iScrollVerticalScrollbar iScrollLoneScrollbar" ></div>
里面还包含了
<div class="iScrollIndicator" ></div>
第一个是滚动区域,第二个是滚动条。拿到Element就好办了,css给定样式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
.iScrollVerticalScrollbar { position: absolute; z-index: 9999; width: 0.1rem; bottom: 2px; top: 2px; right: 0; overflow: hidden; } .iScrollIndicator { position: absolute; width: 0.08rem; height: 0.3rem; background: rgba(255,255,255,0.6); border-radius: 0.1rem; } |
大功告成!
当然,IScroll不止这点功能,官方文档后面还有无限滚动等高级用法,以后用到再添加。