具体情况是这样子的,自己想写一个上拉加载,下拉刷新的插件。总体效果还是实现了的。
js代码如下:
/*
doms//调用scroll_load方法时传入的滑动内容盒子
fn//具体页面加载方法名
fn1//具体页面刷新方法
*/
function scroll_load( doms, fn, fn1) {
var controller = {
_scrollBox_parent: '', //外层盒子
_scrollBox: doms, //正文盒子
_Hight: '', //外层盒子高度
_scrollBoxHeight: '', //正文盒子实际高度
_scrollNum: '', //正文可滚动距离
_scrollTop: 0, //记录被卷起的高度
_elasticTop: 0, //记录下拉弹动距离
_elasticBottom: 0, //记录上拉弹动距离
_elastic: 50, //上下弹动最大距离
flag: '', //记录上下临界状态,触发对应方法
frist:function(){
controller._scrollBox_parent=document.getElementById(doms).parentNode;
controller._scrollBox=document.getElementById(doms);
controller.init();
},
init: function() {
controller._Hight = get_height(controller._Hight, controller._scrollBox_parent); //获取屏幕高度
controller._scrollBoxHeight = get_height(controller._scrollBoxHeight, controller._scrollBox);
controller._scrollNum = controller._scrollBoxHeight - controller._Hight; //获取可滚动高度
}
}
controller.frist();
controller._scrollBox.addEventListener('touchstart', t_start, false);
function get_height(o_sty, _dom) {
if(window.getComputedStyle) {
o_sty = window.getComputedStyle(_dom, null).height; // 非IE
} else {
o_sty = _dom.currentStyle.height; // IE
}
return parseInt(o_sty);
}
function t_start(event) {
var touch = event.targetTouches[0]; //touches数组对象获得屏幕上所有的touch,取第一个touch
startPos = {
x: touch.pageX,
y: touch.pageY,
time: +new Date
}; //取第一个touch的坐标值
isScrolling = 0; //这个参数判断是垂直滚动还是水平滚动
this.addEventListener('touchmove', t_move, false);
this.addEventListener('touchend', t_end, false);
}
function t_move(event) {
if(event.targetTouches.length > 1 || event.scale && event.scale !== 1) return;
var touch = event.targetTouches[0];
endPos = {
x: touch.pageX - startPos.x,
y: touch.pageY - startPos.y
};
//判断方向
//根据方向,判断滑动触发临界点
//根据临界点调用相应外部函数
controller._scrollTop = controller._scrollBox_parent.scrollTop; //实时获取卷起距离
if(endPos.y > 0) {
//下拉
if(controller._scrollTop === 0) {
//触发下拉刷新临界点,可动态下滑区域,开始弹动效果
//设置flag,结束滑动后触发刷新
controller.flag = 0; //下拉临界,刷新
if(controller._elasticTop < controller._elastic) {
controller._elasticTop += 1;
controller._scrollBox.style.transform = "translateY(" + controller._elasticTop * 1 + "px)"
}
}
} else {
//上拉
if(controller._scrollNum > 0) {
//获取可滚动高度大于0
if(controller._scrollTop == controller._scrollNum) {
//下拉到文档底部,触发上拉加载临界点,可动态上滑区域,开始弹动效果
//设置flag,结束滑动后触发加载
controller.flag = 1; //上拉临界,加载
if(controller._elasticBottom < controller._elastic) {
controller._elasticBottom += 1; //上拉弹动距离
controller._scrollBox.style.transform = "translateY(" + controller._elasticBottom * -1 + "px)"
}
}
} else {
controller.flag = 1; //上拉临界,加载
controller._elasticBottom += 1;
controller._scrollBox.style.transform = "translateY(" + controller._elasticBottom * -1 + "px)"
}
}
}
function t_end(event) {
var duration = +new Date - startPos.time; //滑动的持续时间
this.removeEventListener('touchmove', t_move, false);
this.removeEventListener('touchend', t_end, false);
if(controller.flag == 0) {
controller.flag='';
//调用刷新
controller._elasticTop = 0;
controller._scrollBox.style = "";
fn1();
} else if(controller.flag == 1) {
//调用加载
console.log(controller.flag);
controller.flag='';
controller._elasticBottom = 0;
controller._scrollBox.style = "";
fn();
}
controller.init(); //刷新高度数值
}
}
问题出现在方法监听t_end方法出发后,需要重新获取页面dom的样式属性值(特别是在加载新的数据后),我并没有对页面元素的样式做其他处理(至少在没有达到我设置的临界条件前),可是我在页面上看到的效果确实如下情况(很抱歉不能截图):
当我刷新页面,(上拉)触摸开始-移动-结束这一个流程走完,不触发临界条件(不触发加载的上拉距离)时,在滑动过程中,正常,当停止滑动,触发t_end方法时,页面又会回弹到页面顶部,再间隔大概一秒后再回到第一个流程后scrollTop的位置,后面都是会出现这个情况。通俗讲就是首先页面上滚,手指(鼠标)松开后,它会快速回到顶部位置,间隔一下后再回到刚刚停止的位置。我在t_end方法中做了一些参数的重置处理,并重新调用一次init方法,重新获取滚动内容的实际高度。为什么会出现一个渲染的间隔呢?