IScroll的使用-方向键绑定&自定义滚动条样式

之前在webkit上开发一个滚动控件,需要完成的是一段文字,上下键可以滚动,且自定义滚动条。第一想法就是浏览器原生overflow:scroll,且webkit支持自定义滚动条样式:

webkit自定义滚动条样式:

/*定义滚动条高宽及背景 高宽分别对应横竖滚动条的尺寸*/
::-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函数里面

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就丰富多了:

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:

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

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给定样式:

.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不止这点功能,官方文档后面还有无限滚动等高级用法,以后用到再添加。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注