在web阶段的时候,由于各种拖拽之类的效果,需要涉及各类的鼠标事件,比较典型的就是onmousedown, onmousemove, onmouseup,依赖这三个事件基本上就能够实现web页面上的拖拽效果了。
随着移动端的发展,在移动端实现拖拽的效果,变得越来越普遍,但是移动端却没法应用各种鼠标事件,所以类似于上述三种鼠标事件的触摸事件逐渐成为必备,touchstart, touchmove, touchend。初初接触时,总感觉高深无比,很难接受,最近在项目里面就遇到一个此类需求。
页面本身具有滚动条,然后在页面的最底部有一个引导符号,类似于向上滑动的那种,然后就拖动屏幕向上滑,跳转页面也好,做出类似于Parallax 视差滚动也行,总之要求就是监听向上滑动一定距离之后,完成相应的操作。
由于只有这么一个需求,再引入Parallax.js或者别的插件的话,感觉都不是很划算,想想还不如自己造个轮子呢。在某度的帮助下,决定使用触屏滑动事件,借鉴前任经验之后,发现其实跟鼠标拖拽基本类似啊。
首先定义一些变量:
var startPosition, endPosition, deltaX, deltaY, touchGap = 0;
var viewH, contentH, scrollTop;
方便在触屏事件中使用。接着开始看触屏事件的实现过程:
$('.content').on('touchstart', function(e){
var touch = e.touches[0];
startPosition = {
x: touch.pageX,
y: touch.pageY
}
});
获取触摸到屏幕的位置,看看鼠标事件的代码:
$('.content').on('mousedown', function(e){
var _this = this;
startPosition = {
x: e.clientX - _this.offsetLeft,
y: e.clientY - _this.offsetTop
}
});
对比一下,区别在哪里?
由于触摸屏接触的多数为手指,就不像鼠标那样只接触到一个点了,所以触摸位置需要取 e.touches[0],触摸屏上所有滑动都应该是相对于整个屏幕来滑动的,类似于web上拖拽某一个区块的需求相对比较少,所以在移动端也不需要计算点击位置相对于内容区域左边距的距离了,就这么两点区别,其他的就可以说完全类似于鼠标事件了。
后面包括touchmove,touchend其实也完全可以对照mousemove,mouseup来实现。
$('.content').on('touchmove', function(e){
var touch = e.touches[0];
endPosition = {
x: touch.pageX,
y: touch.pageY
}
});
由于我的需求里面只涉及到了向上滑动,所以这里其实根本都不需要获取任何关于水平方向的距离,即touch.pageX,为了实现更好的用户体验,在向上滑动的时候,最好也能够将页面向上推动。
$('.content').on('touchmove', function(e){
var touch = e.touches[0];
endPosition = {
x: touch.pageX,
y: touch.pageY
}
deltaY = endPosition.y - startPosition.y;Math.pow(Math.abs(deltaY), 2));
touchGap = deltaY;
if (deltaY <0) {
$(this).css({
'transform': '-webkit-translateY('+ deltaY +'px)',
'transform': 'translateY('+ deltaY +'px)'
});
}
});
最后所有的操作都需要在触屏结束的那刻去完成,有一个注意事项就是在页面没有滑动到底部的时候,是不能够触发这些事件的,所以需要多一笔计算,滚动条已经滑动到底部了。
$('.content').scroll(function(){
viewH =$(this).height(),//可见高度
contentH =$(this).get(0).scrollHeight,//内容高度
scrollTop =$(this).scrollTop();//滚动高度
if(contentH - viewH - scrollTop <= 50) {
// 滚动条已经到达距离底部50像素以内
$('.content').on('touchend', function(){
// 触摸滑动结束之后,需要将页面返回到滑动之前的位置
$(this).css({
'transform': '-webkit-translateY(0)',
'transform': 'translateY(0)'
});
// 其他任何自定义的操作
}
});
这就完成了,在底部上拉之后需要跳转页面的需求了。