IT技术博客大学习 共学习 共进步

AlloyTouch实现下拉刷新

腾讯AlloyTeam 2017-02-06 23:14:23 浏览 2,542 次

效果展示

你也可以点击这里访问Demo
可以点击这里查看代码


背景

在手机QQ内部,其实客户端提供了下拉刷新的能力,拖动整个webview进行下拉刷新,loading以及loading相关的wording和动画都是客户端的。解决了一部分需要下拉场景的问题。但是在某些场景下,还是需要web拥有自身的下拉刷新的能力。比如:

  • 需要统一IOS和安卓的体验

  • 需要自定义下拉刷新动画

  • 需要已web内的背景或者其他Dom元素有联动交互反馈

而拖动整个webview的下拉刷新无法满足这些场景。AlloyTouch很明显非常擅长处理web下拉刷新的需求。

页面骨架实现

pullRefresh在AlloyTouch header的下面,其中:
header zIndex > pullRefresh zIndex >wrapper和scroller的 zIndex。

下拉动画实现

看以看到,下拉到一定程度,箭头有个旋转动画,以及wording描述也会变化。这里主要利用js去切换class去实现,动画使用CSS transition实现。所以要预先定义好两种class。

.arrow{
    margin-top:5px;
    margin-bottom:5px;
}
 
.arrow:after{
    content:"Pull to refresh";
}
    
.arrow_up.arrow:after{
    content:"Release to refresh";
}
 
.arrow_up img{
    transform:rotateZ(180deg);
    -webkit-transform:rotateZ(180deg);
}
 
.pull_refresh img{
    width:20px;
    transition:transform.4sease;
}

通过上面定要好的class,在js逻辑里面只需要负责remove和add arrow_up clas便可以实现箭头旋转和wording的切换。

Loading动画实现

<svg width='40px'height='40px'xmlns="http://www.w3.org/2000/svg"viewBox="0 0 100 100"preserveAspectRatio="xMidYMid"class="uil-default">
    <rectx="0"y="0"width="100"height="100"fill="none"class="bk"></rect><rectx='46.5'y='40'width='7'height='20'rx='5'ry='5'fill='#00a9f2'transform='rotate(0 50 50) translate(0 -30)'>
        <animate attributeName='opacity'from='1'to='0'dur='1s'begin='0s'repeatCount='indefinite'/>
    </rect><rectx='46.5'y='40'width='7'height='20'rx='5'ry='5'fill='#00a9f2'transform='rotate(30 50 50) translate(0 -30)'>
        <animate attributeName='opacity'from='1'to='0'dur='1s'begin='0.08333333333333333s'repeatCount='indefinite'/>
       ...
       ...
</svg>

loading效果使用SVG去实现,利用12个rect的 indefinite animate去实现。begin代表开始时间有个递增达到loading的效果。

核心实现

varscroller=document.querySelector("#scroller"),
    arrow=document.querySelector("#arrow"),
    pull_refresh=document.querySelector("#pull_refresh"),
    list=document.querySelector("#list"),
    index=0;
 
//给pull_refresh注入transform属性并且关闭透视投影
Transform(pull_refresh,true);
//给scroller注入transform属性并且关闭透视投影
Transform(scroller,true);
 
newAlloyTouch({
    touch:"#wrapper",
    target:scroller,
    property:"translateY",  
    initialVaule:0,
    min:window.innerHeight-45-48-2000,
    max:0,
    change:function(value){
        //pull_refresh的translateY由scroller的value决定,所以向下拉scroller的时候,可以拉动pull_refresh
        pull_refresh.translateY=value;
    },
    touchMove:function(evt,value){
        if(value>70){//当下拉到达70px的时候下箭头变成上箭头并且修改wording
            //为了代码简洁,直接使用classList
            //http://caniuse.com/#search=classList
            //下箭头变成上箭头并且修改wording
            arrow.classList.add("arrow_up");
        }else{  //当下拉未到达70px上箭头变成下箭头并且修改wording
            arrow.classList.remove("arrow_up");
        }
    },
    touchEnd:function(evt,value){
        if(value>70){
            //运动到60px的地方,用来显示loading
            this.to(60);
            //模拟请求~~~
            mockRequest(this);
            //return false很重要,用来防止执行alloytouch内部超出边界的回弹和惯性运动
            returnfalse;
        }
    }
});
 
//模拟请求~~~
functionmockRequest(at){
    //显示loading~~
    pull_refresh.classList.add("refreshing");
    //模拟cgi请求
    setTimeout(function(){
        vari=0,
            len=3;
        for(;i<len;i++){
            varli=document.createElement("li");
            li.innerHTML="new row "+index++;
            list.insertBefore(li,list.firstChild);
        }
        //重置下拉箭头和wording
        arrow.classList.remove("arrow_up");
        //移除loading
        pull_refresh.classList.remove("refreshing");
        //回到初始值
        at.to(at.initialVaule);
        //由于加了三个li,每个li高度为40,所以min要变得更小
        at.min-=40*3;
    },500);
}

不废话,都在注释里。

开始AlloyTouch

Github:https://github.com/AlloyTeam/AlloyTouch

原文地址:https://github.com/AlloyTeam/AlloyTouch/wiki/Pull-to-refresh

建议继续学习

  1. WordPress插件开发 -- 在插件使用数据库存储数据 (阅读 29,000)
  2. 分享一个JQUERY颜色选择插件 (阅读 14,062)
  3. jQuery Color Animations颜色动画插件 (阅读 8,341)
  4. 精于图片处理的10款jQuery插件 (阅读 7,260)
  5. vim 常用插件推荐 (阅读 7,021)
  6. vim的一个js代码整理的插件jsbeautify.vim (阅读 6,020)
  7. nyroModal:强大的jQuery弹出层插件 (阅读 5,801)
  8. 如何创建google浏览器插件 (阅读 4,961)
  9. WordPress模板的image.php (阅读 4,661)
  10. [译]原生全屏Javascript API (阅读 4,641)