zoukankan      html  css  js  c++  java
  • 通过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; 
    

      

  • 相关阅读:
    Form.KeyPreview 属性
    键盘输入、鼠标输入、焦点处理
    KeyDown,KeyPress 和KeyUp
    C#反射实例应用--------获取程序集信息和通过类名创建类实例
    Attribute操作的性能优化方式
    OBjective-C:atomic和nonatomic的区别
    Objective-C:OC内部可变对象和不可变对象的深(复制)拷贝问题思考:
    Objective-C:三种文件导入的方式比较
    Objective-C:保留计数器思想的详解(对象的保留和所有权的释放)
    Objective-C:深复制(拷贝)
  • 原文地址:https://www.cnblogs.com/windyfancy/p/5173836.html
Copyright © 2011-2022 走看看