原文地点:https://github.com/AlloyTeam/AlloyTouch/wiki/Pull-to-refresh
结果展现
扫码体验
背景
在手机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 .4s ease;
}
经由过程上面定要好的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">
<rect x="0" y="0" width="100" height="100" fill="none" class="bk"></rect><rect x='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><rect x='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的结果。
中心完成
var scroller = 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);
new AlloyTouch({
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内部超越边境的回弹和惯性活动
return false;
}
}
});
//模仿要求~~~
function mockRequest(at) {
//显现loading~~
pull_refresh.classList.add("refreshing");
//模仿cgi要求
setTimeout(function () {
var i = 0,
len = 3;
for (; i < len; i++) {
var li = 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
任何看法和发起迎接new issue,AlloyTouch团队会第一时刻反应。