移动端 事件常用函数 整理备份

tap事件

tap 事件相当于 pc 浏览器中的 click 效果,虽然在触屏设备上 click 事件仍然可用,但是在很多设备上,click 会存在一些延迟,如果想要快速响应的 “click” 事件,需要借助 touch 事件来实现。

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 ){
    console.log( ‘fire tap event‘ );
  }
}, false );



对于上面代码;可以再封装一下:
<button id="btn">点击</button>

<script>
var mySky = {
        tap: function(obj, fun) {
              var start_x = 0,
                  start_y = 0; 
              obj.addEventListener(‘touchstart‘,function(e){
                  start_x = e.touches[0].clientX;
                  start_y = e.touches[0].clientY;   //IE下此属性不规范,它们的最小值不是0而是2
                  document.addEventListener(‘touchend‘, touEnd, false);
              });
              function touEnd(e){
                  var endX = e.changedTouches[0].clientX,
                      endY = e.changedTouches[0].clientY;
                  if(Math.abs(endX - start_x) < 6 && Math.abs(endY - start_y) < 6) {
                      fun.call(obj,e);
                  }
                  document.removeEventListener(‘touchend‘, touEnd, false);
              };
          }
}



   var btn=document.getElementById("btn");
   mySky.tap(btn,function(){
      alert(‘我可以点击‘); 
      });
</script>

 

 

doubleTap事件

doubleTap 事件是当手指在相同位置范围内和极短的时间内两次敲击屏幕时触发的事件。在部分浏览器下,doubleTap 事件会选中文本,如果不希望选中文本,可以给元素添加 user-select:none 的 css 属性。

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;
        console.log( ‘fire double tap event‘ );
      }
    }
    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;
                  console.log( ‘fire double tap event‘ );
              }, 400 );
          }
      }
      else{
          firstTouchEnd = true;
      }
  }, true ); 
 // iOS 上手指多次敲击屏幕时的速度过快不会触发 click 事件
element.addEventListener( ‘click‘, function( e ){
  if( dTapTimer ){
    clearTimeout( dTapTimer );
    dTapTimer = null;
    firstTouchEnd = true;
  }
}, false ); 
 } 
  

 

longTap事件

longTap 事件是当手指长时间按住屏幕保持不动时触发的事件。

 

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(){
    console.log( ‘fire long tap event‘ );
  }, 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事件

swipe 事件是当手指在屏幕上滑动后触发的事件,根据手指滑动的方向又分为 swipeLeft (向左)、swipeRight (向右)、swipeUp (向上)、swipeDown (向下)。

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 ){
      console.log( ‘fire swipe left event‘ );
      isSwipe = true;
    }
    else if( distanceX < -20 ){
      console.log( ‘fire swipe right event‘ );    
      isSwipe = true;
    }
  }
  else{
    if( distanceY > 20 ){
      console.log( ‘fire swipe up event‘ );        
      isSwipe = true;
    }
    else if( distanceY < -20 ){
      console.log( ‘fire swipe down event‘ );         
      isSwipe = true;
    }
  } 
   if( isSwipe ){
    console.log( ‘fire swipe event‘ );
  }
}, false ); 
  

 

 

 

完成封装:

https://github.com/chenmnkken/monoevent/wiki/MonoEvent-%E7%9A%84%E4%BD%BF%E7%94%A8%E6%96%87%E6%A1%A3

http://levi.cg.am/archives/3546

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。