移動端touch事件封裝

<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no">
<title>無標題文檔</title>
<style>
	div{width:100px;height:100px;line-height:100px;margin-bottom:10px;background:red;text-align:center;color:#fff;}
</style>
<script>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no">
<title>無標題文檔</title>
<style>
    div{width:100px;height:100px;line-height:100px;margin-bottom:10px;background:red;text-align:center;color:#fff;}
</style>
<script>
    /***
        @name:觸屏事件
        @param {string} element dom元素
               {function} fn 事件觸發函數
    ***/
    
    var touchEvent={
        
        /*單次觸摸事件*/
        tap:function(element,fn){
            var startTx, startTy;
            element.addEventListener('touchstart',function(e){
              var touches = e.touches[0];
              startTx = touches.clientX;
              startTy = touches.clientY;
            }, false );
            
            element.addEventListener('touchend',function(e){
              var touches = e.changedTouches[0],
              endTx = touches.clientX,
              endTy = touches.clientY;
              // 在部分設備上 touch 事件比較靈敏,致使按下和鬆開手指時的事件座標會出現一點點變化
              if( Math.abs(startTx - endTx) < 6 && Math.abs(startTy - endTy) < 6 ){
                fn();
              }
            }, false );
        },
        
        /*兩次觸摸事件*/
        doubleTap:function(element,fn){
            var isTouchEnd = false,
            lastTime = 0,
            lastTx = null,
            lastTy = null,
            firstTouchEnd = true,
            body = document.body,
            dTapTimer, startTx, startTy, startTime;
            element.addEventListener( 'touchstart', function(e){
              if( dTapTimer ){
                clearTimeout( dTapTimer );
                dTapTimer = null;
              }
              var touches = e.touches[0];
              startTx = touches.clientX;
              startTy = touches.clientY;   
            }, false );
            element.addEventListener( 'touchend',function(e){
              var touches = e.changedTouches[0],
              endTx = touches.clientX,
              endTy = touches.clientY,
              now = Date.now(),
              duration = now - lastTime;
              // 首先要確保能觸發單次的 tap 事件
              if( Math.abs(startTx - endTx) < 6 && Math.abs(startTx - endTx) < 6 ){
                // 兩次 tap 的間隔確保在 500 毫秒之內
                if(duration < 301 ){
                  // 本次的 tap 位置和上一次的 tap 的位置容許必定範圍內的偏差
                  if( lastTx !== null &&
                    Math.abs(lastTx - endTx) < 45 &&
                    Math.abs(lastTy - endTy) < 45 ){
                      firstTouchEnd = true;
                      lastTx = lastTy = null;
                      fn();
                    }
                  }
                  else{
                    lastTx = endTx;
                    lastTy = endTy;
                  }
                }
                else{
                  firstTouchEnd = true;
                  lastTx = lastTy = null;
                }
                lastTime = now;
              }, false );
              // 在 iOS 的 safari 上手指敲擊屏幕的速度過快,
              // 有必定的概率會致使第二次不會響應 touchstart 和 touchend 事件
              // 同時手指長時間的touch不會觸發click
              if(~navigator.userAgent.toLowerCase().indexOf('iphone os')){
                body.addEventListener( 'touchstart', function(e){
                  startTime = Date.now();
                }, true );
                body.addEventListener( 'touchend', function(e){
                  var noLongTap = Date.now() - startTime < 501;
                  if(firstTouchEnd ){
                    firstTouchEnd = false;
                    if( noLongTap && e.target === element ){
                      dTapTimer = setTimeout(function(){
                        firstTouchEnd = true;
                        lastTx = lastTy = null;
                        fn();
                      },400);
                    }
                  }
                  else{
                    firstTouchEnd = true;
                  }
                }, true );
                // iOS 上手指屢次敲擊屏幕時的速度過快不會觸發 click 事件
                element.addEventListener( 'click', function( e ){
                  if(dTapTimer ){
                    clearTimeout( dTapTimer );
                    dTapTimer = null;
                    firstTouchEnd = true;
                  }
                }, false );
            }    
        },
        
        /*長按事件*/
        longTap:function(element,fn){
            var startTx, startTy, lTapTimer;
            element.addEventListener( 'touchstart', function( e ){
              if( lTapTimer ){
                clearTimeout( lTapTimer );
                lTapTimer = null;
              }
              var touches = e.touches[0];
              startTx = touches.clientX;
              startTy = touches.clientY;
              lTapTimer = setTimeout(function(){
                fn();
              }, 1000 );
              e.preventDefault();
            }, false );
            element.addEventListener( 'touchmove', function( e ){
              var touches = e.touches[0],
                endTx = touches.clientX,
                endTy = touches.clientY;
              if( lTapTimer && (Math.abs(endTx - startTx) > 5 || Math.abs(endTy - startTy) > 5) ){
                clearTimeout( lTapTimer );
                lTapTimer = null;
              }
            }, false );
            element.addEventListener( 'touchend', function( e ){
              if( lTapTimer ){
                clearTimeout( lTapTimer );
                lTapTimer = null;
              }
            }, false );    
        },
        
        /*滑屏事件*/
        swipe:function(element,fn){
            var isTouchMove, startTx, startTy;
            element.addEventListener( 'touchstart', function( e ){
              var touches = e.touches[0];
              startTx = touches.clientX;
              startTy = touches.clientY;
              isTouchMove = false;
            }, false );
            element.addEventListener( 'touchmove', function( e ){
              isTouchMove = true;
              e.preventDefault();
            }, false );
            element.addEventListener( 'touchend', function( e ){
              if( !isTouchMove ){
                return;
              }
              var touches = e.changedTouches[0],
                endTx = touches.clientX,
                endTy = touches.clientY,
                distanceX = startTx - endTx
                distanceY = startTy - endTy,
                isSwipe = false;
              if( Math.abs(distanceX)>20||Math.abs(distanceY)>20 ){
                fn();
              }
            }, false );    
        },
        
        /*向上滑動事件*/
        swipeUp:function(element,fn){
            var isTouchMove, startTx, startTy;
            element.addEventListener( 'touchstart', function( e ){
              var touches = e.touches[0];
              startTx = touches.clientX;
              startTy = touches.clientY;
              isTouchMove = false;
            }, false );
            element.addEventListener( 'touchmove', function( e ){
              isTouchMove = true;
              e.preventDefault();
            }, false );
            element.addEventListener( 'touchend', function( e ){
              if( !isTouchMove ){
                return;
              }
              var touches = e.changedTouches[0],
                endTx = touches.clientX,
                endTy = touches.clientY,
                distanceX = startTx - endTx
                distanceY = startTy - endTy,
                isSwipe = false;
              if( Math.abs(distanceX) < Math.abs(distanceY) ){
                  if( distanceY > 20 ){
                      fn();       
                      isSwipe = true;
                  }
              }
            }, false );    
        },
        
        /*向下滑動事件*/
        swipeDown:function(element,fn){
            var isTouchMove, startTx, startTy;
            element.addEventListener( 'touchstart', function( e ){
              var touches = e.touches[0];
              startTx = touches.clientX;
              startTy = touches.clientY;
              isTouchMove = false;
            }, false );
            element.addEventListener( 'touchmove', function( e ){
              isTouchMove = true;
              e.preventDefault();
            }, false );
            element.addEventListener( 'touchend', function( e ){
              if( !isTouchMove ){
                return;
              }
              var touches = e.changedTouches[0],
                endTx = touches.clientX,
                endTy = touches.clientY,
                distanceX = startTx - endTx
                distanceY = startTy - endTy,
                isSwipe = false;
              if( Math.abs(distanceX) < Math.abs(distanceY) ){
                  if( distanceY < -20  ){
                      fn();       
                      isSwipe = true;
                  }
              }
            }, false );    
        },
        
        /*向左滑動事件*/
        swipeLeft:function(element,fn){
            var isTouchMove, startTx, startTy;
            element.addEventListener( 'touchstart', function( e ){
              var touches = e.touches[0];
              startTx = touches.clientX;
              startTy = touches.clientY;
              isTouchMove = false;
            }, false );
            element.addEventListener( 'touchmove', function( e ){
              isTouchMove = true;
              e.preventDefault();
            }, false );
            element.addEventListener( 'touchend', function( e ){
              if( !isTouchMove ){
                return;
              }
              var touches = e.changedTouches[0],
                endTx = touches.clientX,
                endTy = touches.clientY,
                distanceX = startTx - endTx
                distanceY = startTy - endTy,
                isSwipe = false;
              if( Math.abs(distanceX) >= Math.abs(distanceY) ){
                  if( distanceX > 20  ){
                      fn();       
                      isSwipe = true;
                  }
              }
            }, false );    
        },
        
        /*向右滑動事件*/
        swipeRight:function(element,fn){
            var isTouchMove, startTx, startTy;
            element.addEventListener( 'touchstart', function( e ){
              var touches = e.touches[0];
              startTx = touches.clientX;
              startTy = touches.clientY;
              isTouchMove = false;
            }, false );
            element.addEventListener( 'touchmove', function( e ){
              isTouchMove = true;
              e.preventDefault();
            }, false );
            element.addEventListener( 'touchend', function( e ){
              if( !isTouchMove ){
                return;
              }
              var touches = e.changedTouches[0],
                endTx = touches.clientX,
                endTy = touches.clientY,
                distanceX = startTx - endTx
                distanceY = startTy - endTy,
                isSwipe = false;
              if( Math.abs(distanceX) >= Math.abs(distanceY) ){
                  if( distanceX < -20  ){
                      fn();       
                      isSwipe = true;
                  }
              }
            }, false );    
        }
        
    }
</script>
<script>
    window.onload=function(){
        var aDiv=document.getElementsByTagName("div");
        
        touchEvent.tap(aDiv[0],function(){
            alert("單次觸摸");
        })
        
        touchEvent.doubleTap(aDiv[1],function(){
            alert("兩次觸摸");
        })
        
        touchEvent.longTap(aDiv[2],function(){
            alert("長按");
        })
        
        touchEvent.swipe(document,function(){
            alert("滑屏了");
        })
        
        touchEvent.swipeUp(document,function(){
            alert("向上滑屏了");
        })
        
        touchEvent.swipeDown(document,function(){
            alert("向下滑屏了");
        })
        
        touchEvent.swipeLeft(document,function(){
            alert("向左滑屏了");
        })
        
        touchEvent.swipeRight(document,function(){
            alert("向右滑屏了");
        })
    }
    
</script>
</head>
<body>
    <div class="box1">單次觸摸我</div>
    <div class="box2">兩次觸摸</div>
    <div class="box3">長按我</div>
    <span>試一試在屏幕上任意區域滑動</span>
</body>
</html>
相關文章
相關標籤/搜索