通过html5 touch事件封装手势识别组件

html5移动端新增了touchstart,touchmove,touchend事件,利用这3个事件,判断手指的点击和划动轨迹,我们可以封装各种手势的识别功能,

这3个事件和pc端的mousedown,mousemove,mouveup非常类似,不同的是touch事件可以有多个点击的点,而鼠标每次只有一个点,我们即然是做组件封装,就要考虑在pc上调试的情况,否则用手机调试非常不方便,通过对mouse事件的处理,可以一套代码同时兼容pc端和移动端。

下面来逐步封装一个滑动手势(swipe)的组件

1.判断是否触摸屏

我们使用能力检测,检测是否支持touchstart事件,就可以知道是否是触摸屏,因为触摸事件可以通过document.ontouchstart=function(){} 这样的方式定义,用in操作符判断即可,对于win8,触屏能力会在navigator对象中生成一个msPointerEnabled属性。

 if (‘ontouchstart‘ in window || ‘ontouchstart‘ in document) {
            //iOS & android
            supportsTouch = true;
 } else if(window.navigator.msPointerEnabled) {
            //Win8
            supportsTouch = true;
 }

2.同时兼容鼠标和触摸屏的事件绑定

我们根据上一步的判断,如果支持toucestart就绑定对应的touchstart,touchmove,touchend事件,如果不支持,则绑定对应的3个鼠标事件

if(isSupportTouch()){
el.addEventListener(‘touchstart‘,touchStart);
el.addEventListener(‘touchend‘,touchEnd);
el.addEventListener(‘touchmove‘,touchMove);

}else{

el.addEventListener(‘mousedown‘,touchStart);
el.addEventListener(‘mouseup‘,touchEnd);
el.addEventListener(‘mousemove‘,touchMove);

}

3.获取点击的点位置信息(兼容鼠标和触摸屏)

从事件参数中可以得到位置信息,如果是鼠标,则通过e.pageX,e.pageY获取点击位置相对于页面根节点的坐标,如果是触摸屏,则e.touches对象是一个点击点位置的数组,包含多个手指的点击位置,我们暂时只处理一只手指的情况,所以取e.touches[0].pageX,e.touches[0].pageY.

function touchStart(e){
var t=e.touches?e.touches[0]:e;
startPoint={x:t.pageX,y:t.pageY};

}

4.判断手指滑动方向

在toucemove事件中判断手指划动,toucemove事件会连续触发,为了过滤掉划动距离太短的无效滑动,我们可以判断pageX和pageY和上一次位置的偏移量超过两个像素才认为是有效事件,然后再判断滑动方向,当前点击位置的(x,y)坐标,减去上一个位置的(x,y)坐标,如果x轴的差值大,就认为是左右滑,如果是y轴的差值大就认为是上下滑,再进一步判断差值 为正数则是左或上,差值为负数则为右或下。代码如下:

function getSwipeDirection(x1, x2, y1, y2) {
return Math.abs(x1 - x2) >=
Math.abs(y1 - y2) ? (x1 - x2 > 0 ? ‘left‘ : ‘right‘) : (y1 - y2 >0 ? ‘up‘ : ‘down‘)
}

5.jquery插件封装

为了更方便使用,可以封装成jquery插件,我们常说的jquery对象其实是指继随自jquery原型的对象,jquery的原型是指$.fn,只要扩展$.fn即可,

如$.fn.methodName=function(){//code}

或用$.fn.extend({

methodName:funciton(){//code}

})

完整代码如下:

function TouchEvent(){
    var self=this,element=$(this);
    var el=element[0],isTouching,isSwipe,startTime,startPoint,currentPoint;

    if(arguments.length>1){
        var eventType=arguments[0];
    }
    var callback=arguments[arguments.length-1];
    function doAction(type,args){
        args.type=type;
        if(eventType){
            if(eventType==type){
                callback.call(self,args);
            }
        }else{
            callback.call(self,args);
        }
    }
    function getSwipeDirection(x1, x2, y1, y2) {
        return Math.abs(x1 - x2) >=
            Math.abs(y1 - y2) ? (x1 - x2 > 0 ? ‘left‘ : ‘right‘) : (y1 - y2 >0 ? ‘up‘ : ‘down‘)
    }
    function isSupportTouch(){
        var supportsTouch = false;
        if (‘ontouchstart‘ in window || ‘ontouchstart‘ in document) {
            //iOS & android
            supportsTouch = true;
        } else if(window.navigator.msPointerEnabled) {
            //Win8
            supportsTouch = true;
        }
        return supportsTouch;
    }
    function touchStart(e){
        isTouching=true;
        startTime=new Date();
            var t=e.touches?e.touches[0]:e;
        startPoint={x:t.pageX,y:t.pageY};

    }
    function touchMove(e){
        if(isTouching){

            var t=e.touches?e.touches[0]:e;
            var p={x:t.pageX,y:t.pageY};
            currentPoint=p;
            var x1=startPoint.x,x2=currentPoint.x,y1=startPoint.y,y2=currentPoint.y;
            if(Math.abs(x1-x2)>2 || Math.abs(y1-y2)>2){
                isSwipe=true;
                var direction=getSwipeDirection(x1,x2,y1,y2);
                //console.log(direction);
                e.direction=direction;
                doAction("swipe",e);
            }

        }
    }
    function touchEnd(e){
        isTouching=false;
        if(!isSwipe){
            e["long"]=new Date()-startTime>1000;
            doAction("tap",e);
            //console.log("tap");
        }else{

            var x1=startPoint.x,x2=currentPoint.x,y1=startPoint.y,y2=currentPoint.y;
            var direction=getSwipeDirection(x1,x2,y1,y2);
            console.log(direction)
            doAction("swipeEnd",{direction:direction});
        }
        isSwipe=false;
    }
    if(isSupportTouch()){
        el.addEventListener(‘touchstart‘,touchStart);
        el.addEventListener(‘touchend‘,touchEnd);
        el.addEventListener(‘touchmove‘,touchMove);
        //el.addEventListener(‘touchcancel‘,actionFinsh);
    }else{

        el.addEventListener(‘mousedown‘,touchStart);
        el.addEventListener(‘mouseup‘,touchEnd);
        el.addEventListener(‘mousemove‘,touchMove);

    }
}

$.fn.touchEvent = TouchEvent;

  

时间: 2024-10-05 00:27:03

通过html5 touch事件封装手势识别组件的相关文章

(一)html5 touch事件实现页面上下滑动

最近做的做那个app的项目由于用overflow:hidden导致了很多问题,于是决定研究下html5的touch事件.想找个全面点的帖子真是难死了,虽然好多关于html5 touch的文章但大多都是介绍touch事件或者很简短的小demo. 下午好生研究了下终于搞出了个比较全面的上下滑动的小demo,代码比较简单. 下面是完整代码,我把几个重要的地方做了红色标记 <!doctype html> <html lang="en"> <head> <

React-Native系列Android——Touch事件原理及状态效果

Native原生相比于Hybrid或H5最大优点是具有流畅和复杂的交互效果,触摸事件便是其中重要一项,包括点击(Click).长按(LongClick).手势(gesture)等. 以最简单常见的点击(Click)为例,Native组件可以自定义selector,使得被点击的组件具有动态效果,Android 5.0以上甚至可以有涟漪效果(Material Design).而这些在Hybrid或H5中很难实现,很多时候区分它们与原生最简单的方法就是检验点击交互效果. React-Native的强大

javascript移动设备Web开发中对touch事件的封装实例

在触屏设备上,一些比较基础的手势都需要通过对 touch 事件进行二次封装才能实现.zepto 是移动端上使用率比较高的一个类库,但是其 touch 模块模拟出来的一些事件存在一些兼容性问题,如 tap 事件在某些安卓设备上存在事件穿透的 bug,其他类型的事件也或多或少的存在一些兼容性问题. 于是乎,干脆自己动手对这些常用的手势事件进行了封装,由于没有太多真实的设备来进行测试,可能存在一些兼容性问题,下面的代码也只是在 iOS 7.Andorid 4 上的一些比较常见的浏览器中测试通过. ta

手机站建设HTML5触摸屏touch事件使用介绍

手机站建设HTML5触摸屏touch事件使用介绍技术 maybe yes 发表于2015-01-05 14:42 原文链接 : http://blog.lmlphp.com/archives/56  来自 : LMLPHP后院 市面上手机种类繁多,在触屏手机上运行的网页跟传统PC网页相比还是有很大差别的.由于设备的不同浏览器的事件的设计也不同.传统PC站的 click 和 onmouseover 等事件在一般触屏的手机上也可以使用,但是效果不够好.PC上还没有哪个事件是可以与触屏手机的触摸事件对

【html5构建触屏网站】之touch事件

[html5构建触屏网站]之touch事件 前言 一个触屏网站到底和传统的pc端网站有什么区别呢,交互方式的改变首当其冲.例如我们常用的click事件,在触屏设备下是如此无力. 手机上的大部分交互都是通过touch来实现的,于是,对于触屏的交互式网站,触摸事件是相当重要的. Apple在iOS 2.0中引入了触摸事件API,Android正迎头赶上这一事实标准,缩小差距.最近一个W3C工作组正合力制定这一触摸事件规范. 规范 这里我们介绍几种普及得比较好的触摸事件,你可以在绝大多数现代浏览器中来

HTML5触摸屏touch事件使用介绍1

市面上手机种类繁多,在触屏手机上运行的网页跟传统PC网页相比还是有很大差别的.由于设备的不同浏览器的事件的设计也不同.传统PC站的 click 和 onmouseover 等事件在一般触屏的手机上也可以使用,但是效果不够好.PC上还没有哪个事件是可以与触屏手机的触摸事件对应的,为了更好的用户体验,移动站点的建设也需要对不同的事件进行处理. 介绍几种兼容比较好的触摸事件,大部分触屏设备都支持的. touchstart:触摸开始的时候触发 touchmove:触摸时手指在屏幕上滑动的时候触发 tou

iOS开发系列--触摸事件、手势识别、摇晃事件、耳机线控

-- iOS事件全面解析 概览 iPhone的成功很大一部分得益于它多点触摸的强大功能,乔布斯让人们认识到手机其实是可以不用按键和手写笔直接操作的,这不愧为一项伟大的设计.今天我们就针对iOS的触摸事件(手势操作).运动事件.远程控制事件等展开学习: iOS事件简介 触摸事件 手势识别 运动事件 远程控制事件 iOS事件 在iOS中事件分为三类: 触摸事件:通过触摸.手势进行触发(例如手指点击.缩放) 运动事件:通过加速器进行触发(例如手机晃动) 远程控制事件:通过其他远程设备触发(例如耳机控制

HTML5 例子学习 HT 图形组件

HTML5 例子学习 HT 图形组件 HT 是啥:Everything you need to create cutting-edge 2D and 3D visualization. 这口号是当年心目中的产品方向,接着就朝这个方向慢慢打磨,如今 HT 算是达到了这样的效果,谈不上用尽洪荒之力,但我们对产品结果很满意,特别是 HT 的用户手册,将例子和文档无缝融合一体,小小 10 来兆开发包居然包含了四十五份手册,数百个活生生的 HTML5 例子,还没体验过的同学可以点击 http://www.

转发:iOS开发系列--触摸事件、手势识别、摇晃事件、耳机线控

-- iOS事件全面解析 转载来自崔江涛(KenshinCui) 链接:http://www.cnblogs.com/kenshincui/p/3950646.html 概览 iPhone的成功很大一部分得益于它多点触摸的强大功能,乔布斯让人们认识到手机其实是可以不用按键和手写笔直接操作的,这不愧为一项伟大的设计.今天我们就针对iOS的触摸事件(手势操作).运动事件.远程控制事件等展开学习: iOS事件简介 触摸事件 手势识别 运动事件 远程控制事件 iOS事件 在iOS中事件分为三类: 触摸事