通過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; 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM