之前在webkit上开发一个滚动控件,需要完成的是一段文字,上下键可以滚动,且自定义滚动条。第一想法就是浏览器原生overflow:scroll,且webkit支持自定义滚动条样式:
webkit自定义滚动条样式:
CSS
/*定义滚动条高宽及背景 高宽分别对应横竖滚动条的尺寸*/
::-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);
}
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函数里面
JavaScript
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;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
handleEvent:function(e){
varthat=this;
switch(e.type){
caseSTART_EV:
if(!hasTouch&& e.button !== 0) return;
that._start(e);
break;
caseMOVE_EV:that._move(e);break;
caseEND_EV:
caseCANCEL_EV:that._end(e);break;
caseRESIZE_EV:that._resize();break;
caseWHEEL_EV:that._wheel(e);break;
case'mouseout':that._mouseout(e);break;
caseTRNEND_EV:that._transitionEnd(e);break;
}
}
根本就没有keyEvent,看来偷懒是不行的,官方文档看一下,原来iscroll有5个版本,各自平台都是不一样的,demo中这个估计是移动平台用的iscroll-lite版本,移动平台根本不鸟方向键的。
去github上down下来源码,找了找,build目录下,5个版本都有。用最原始的common版本,这个版本的handleEvent就丰富多了:
JavaScript
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;
}
}
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:
JavaScript
document.addEventListener("keydown", function(evt) {
if (evt.keyCode === keyCodes.ENTER) {
} else {
myScroll && myScroll.handleEvent(evt);
}
}, false);
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
JavaScript
myScroll = new IScroll(document.getElementById('wrapper'), {
keyBindings: true, // 绑定按键事件
scrollbars: 'custom', // 自定义样式
resizeScrollbars: false // 是否自动缩放滚动条
});
1
2
3
4
5
myScroll=newIScroll(document.getElementById('wrapper'),{
keyBindings:true,// 绑定按键事件
scrollbars:'custom',// 自定义样式
resizeScrollbars:false// 是否自动缩放滚动条
});
设置了scrollbars: 'custom',在页面的Elements就可以找到
里面还包含了
第一个是滚动区域,第二个是滚动条。拿到Element就好办了,css给定样式:
CSS
.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;
}
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不止这点功能,官方文档后面还有无限滚动等高级用法,以后用到再添加。