您的位置:首页 > 移动开发

移动端,JS判断滑到页面底部上滑进行操作

2016-06-16 21:18 309 查看
做项目的时候接到小发版以为很小的东西就没放心上,结果还是忽略了很多,造成一些困扰,1 【滚动区高度获取]
document.documentElement.scrollHeight
可以通过【scrollHeight】这个属性去获取,根据【js高性能的理论】像获取这样的属性时页面会再次重绘排版,也就是引起渲染,所以要尽可能的减少这个属性的读取,当然一开始可以获取它的值并保存在一个变量中,这样做貌似是没有问题,但是有一个潜在问题,如果有JS在文档加载完后在你读这个属性之后改变了文档高度,问题就暴露了出来,这个问题曾经困扰了我,后来才发现是有JS偷偷修改了文档高度2【获取首屏高度】
document.documentElement.clientHeight
可以通过【clientHeight】这个属性拿到,首屏的高度,当然根据【js高性能的理论】就算仅仅是读取依然会引起DOM重绘排版,这样的操作必然要减少使用次数,和上面的属性一样,可以读一次就存在一个变量中,实际情况是,有些浏览器的首屏高度是会变化的,大根差50甚至更多,目测根浏览器顶部地址栏有关,向下滑动一个地址栏高度 【clientHeight】读到的属性就会变化,但是只是部分,模拟器不存在这个问题3【读取滚动条距离】
document.querySelector("body").scrollTop
这个没有什么好说的,依然是少读取为妙,依然会引起DOM重绘排版4【检测向上滑动】可以监听【touchstart】事件 与【touchend】事件,检测事件对像的【pageY】属性值的变化,有兼容性的问题是,touchend 事件的触发问题,部分机型(安卓:UC 浏览器),在【touchmove】 事件触发后不再触发【touchend】事件,部分的解决方案是:【touchstart / touchmove】事件中 阻止默认操作,event.preventDefault();但是这样会造成新的问题——页面不能滚动;现在解决方案是【touchend】事件的处理函数,在【toumove】事件执行,但是要闭免多次调用的问题,毕竟【touchmove】事件触发的太频繁,又要避免耗性能的操作;所以使用【setTimemout】,之所以设【100毫秒】的延迟是因为,100毫秒以下延迟几乎无察觉,【UC】 不得不说的UC,在【touchmove】时只改变了一次【pageY】并且大数情况下,一次滑动在7~20之间,兼容处理贴出全码,自行整理5【部分性能优化的代码】
bottomUpwardSlidingDo:function(callback){var start,end,slideNum,winH,bodyH,bodyEle=doc.querySelector("body"),docEle=doc.documentElement,UA =navigator.userAgent,isUC=UA.indexOf("UCBrowser")!=-1||UA.indexOf("Baidu")!=-1||UA.indexOf("MQQBrowser")!=-1,_h,_hStart;slideNum=isUC?6:60;//值越小灵敏度越高doc.addEventListener("touchstart",touchStartHandle,false);!isUC&&doc.addEventListener("touchend",touchEndHandle,false);function touchStartHandle(evt){clearTimeout(_hStart);_hStart=setTimeout(function(){start=evt.touches[0].pageY;},0);}isUC&&doc.addEventListener("touchmove",function(evt){clearTimeout(_h);_h<4000span style="color:#f92672;">=setTimeout(function(){touchEndHandle(evt)},0);},false);function touchEndHandle(evt){if($.BUDS)return;end=evt.changedTouches[0].pageY;if(start-end>slideNum){var scrollTop=bodyEle.scrollTop;winH=docEle.clientHeight;bodyH=docEle.scrollHeight;scrollTop+winH+1>=bodyH&&callback();//之所以加1是因为某些情况下会有1PX偏差,当然也可以稍微加大更加灵敏}//console.log(end,start,end-start,bodyH-scrollTop-winH);}},
【注意事项】动态的改变,html,body 的【overflow】 属性,会影响 【document.documentElement.scrollTop】   的值,最常见场景比如,浮动弹出后禁止页面滚动,PC端常用下面的代码:
$("html,body").css("overflow","hidden");
然而移动端结合上面的代码后就会发现,【document.documentElement.scrollTop】的值会变成,一屏的高度,即便已经将 html body 的【overflow】 设为【auto】因此些时上滑动屏幕达到 控制值时,即便没有到达页面底部,依然会执行回调函数,【解决方案】移动端禁止页面滚动其实很简单,代码如下:
function lockHtml(evt){evt.preventDefault();}document.addEventListener("touchmove",lockHtml,false);document.removeEventListener("touchmove",lockHtml,false);
通过事件的注册与解绑可以实现页面的滚动与否,【有关禁用】有时需要暂时的开关下滑回调的功能,可以通过置
$.BUDS
的值为 true /false 实现,关、开$的值可以根据自己的情况而定,【注意事项】常见的使用场景是滑加载一些信息,为了避免不必要的请求,滑动执行操作后应 阻止容器元素【touchmove】事件冒泡到document 等AJAX请求完毕,元素渲染完毕 再解开,这样可以避免 上滑回调的不正常调用(PS: 页面插入元素DOM ,引擎尺寸没有更新依然会出现多次调用),
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: