天天看點

JS 手勢長按代碼

同時支援長按和點選事件,無依賴版

<!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
    <title>Document</title>
</head>
<style>
    body {
        max- 540px;
        min- 320px;
    }
</style>
<body>
    <button id="longPress">longPress</button>

    <li class="longPress">longPress</li>
    <li class="longPress">longPress</li>
    <li class="longPress">longPress</li>
    <li class="longPress">longPress</li>
</body>
<script>
    
/**
 * 綁定長按事件,同時支援綁定點選事件
 * @param {dom} dom 需要綁定的dom元素
 * @param {fn} longPressCallBack 長按事件執行的方法
 * @param {fn} touchCallBack 點選事件執行的方法
 */
var longPress = function (dom, longPressCallBack, touchCallBack) {
    var timer = undefined;
    var isLongPress = false;

    var setEvent = function (e) {
          e.addEventListener('touchstart', function(event) {
                  timer = setTimeout(function () {
                    isLongPress = true
                  longPressCallBack && longPressCallBack(e);
                }, 500);
          }, false);

          e.addEventListener('touchmove', function(event) {
                 clearTimeout(timer);
          }, false);

          e.addEventListener('touchend', function(event) {
                  if (!isLongPress) touchCallBack && touchCallBack()
                  clearTimeout(timer); 
                  isLongPress = false;
          }, false);
    }

    if (dom.length) {
        // 支援綁定多個元素
          for (var i = 0; i < dom.length; i++) {
            setEvent(dom[i])
        }
    } else {
        setEvent(dom)
    }
}

longPress(document.getElementById('longPress'), function () {
    console.log('longPress')
}, function () {
    console.log('touch');
});

[...document.querySelectorAll('.longPress')].forEach(function (e, i) {
    longPress(e, function () {
        console.log('longPress')
    }, function () {
        console.log('touch');
    });
});
</script>
</html>      

jquery / zepto版本的實作,注意閉包的問題

$.fn.longPress = function(callback) {
  var timer = undefined;
  var $this = this;
  
  // 支援綁定多個元素
  for (var i = 0; i < $this.length; i++) {
    var self = $this[i];
     // 注意這裡的閉包問題
    (function(e){
      self.addEventListener('touchstart', function(event) {
        timer = setTimeout(function () {
          callback(e);
        }, 500);
      }, false);
      self.addEventListener('touchmove', function(event) {
        clearTimeout(timer);
      }, false);
      self.addEventListener('touchend', function(event) {
        clearTimeout(timer);
      }, false);
    })($this[i]);
  }
}

// 調用示例
$(".card-con li").longPress(function(e){
   console.log(e, $(e).index());       
});      

知乎上找到的原生實作:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8"/>
    <title></title>
    <script type="text/javascript" src="http://lib.sinaapp.com/js/jquery/1.9.1/jquery-1.9.1.min.js"></script>
</head>
<body>
<div style="100%;">
    <div id="touchArea" style="90%; height:200px; background-color:#CCC;font-size:100px">長按我</div> 
</div>
<script>
var timeOutEvent=0;
$(function(){
    $("#touchArea").on({
        touchstart: function(e){
            timeOutEvent = setTimeout("longPress()",500);
            e.preventDefault();
        },
        touchmove: function(){
                    clearTimeout(timeOutEvent); 
                timeOutEvent = 0; 
        },
        touchend: function(){
            clearTimeout(timeOutEvent);
            if(timeOutEvent!=0){ 
                alert("你這是點選,不是長按"); 
            } 
            return false; 
        }
    })
});

 
function longPress(){ 
    timeOutEvent = 0; 
    alert("長按事件觸發發"); 
} 

</script>
</body>
</html>