首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

JavaScript 實現移動端手勢滑動方向判斷:左滑刪除、右滑編輯交互詳解

     編輯:程式設計綜合問答

業務場景

移動端列表頁需實現類似微信的交互:列表項左滑顯示「刪除」按鈕,右滑顯示「編輯」按鈕。核心需求是精準判斷手指滑動方向(左/右/上/下),並區分滑動與點擊、長按等手勢。

方案對比

方案優點缺點適用場景
原生 Touch 事件零依賴、體積小、完全可控需手寫閾值邏輯、跨瀏覽器兼容性差極簡專案、不想引入庫
Hammer.js專業手勢識別、支援多點觸控、擴展性強體積 7KB+、API 較複雜複雜手勢識別需求
jQuery Mobile內建 swipeleft/swiperight 事件、語法簡潔庫巨大(~200KB)、維護停滯舊專案已引入 jQM
TouchSwipe (jQuery 插件)輕量(~10KB)、專注滑動、配置豐富需 jQuery 依賴jQuery 體系專案首選

推薦方案:原生 Touch 事件封裝(零依賴、高性能)

核心邏輯

  1. 記錄 touchstart 時的 clientX/clientY
  2. touchmove 時計算位移 deltaX/deltaY
  3. 設定閾值(如 30px)過濾抖動
  4. 判斷主方向:|deltaX| > |deltaY| 為水平滑動,deltaX > 0 右滑,反之左滑
  5. touchend 觸發回調,傳遞方向與位移量

完整實現代碼

function bindSwipe(element, callbacks) {
  let startX, startY, startTime;
  
  element.addEventListener('touchstart', e => {
    const touch = e.touches[0];
    startX = touch.clientX;
    startY = touch.clientY;
    startTime = Date.now();
  }, { passive: true });

  element.addEventListener('touchmove', e => {
    if (!startX) return;
    const touch = e.touches[0];
    const deltaX = touch.clientX - startX;
    const deltaY = touch.clientY - startY;
    
    // 防止頁面滾動干擾:水平滑動超過閾值時阻止默認
    if (Math.abs(deltaX) > 30 && Math.abs(deltaX) > Math.abs(deltaY)) {
      e.preventDefault();
    }
  }, { passive: false });

  element.addEventListener('touchend', e => {
    if (!startX) return;
    const deltaX = e.changedTouches[0].clientX - startX;
    const deltaY = e.changedTouches[0].clientY - startY;
    const duration = Date.now() - startTime;
    
    // 有效滑動判斷:位移>30px、耗時<300ms、水平為主
    if (Math.abs(deltaX) > 30 && duration < 300 && Math.abs(deltaX) > Math.abs(deltaY)) {
      callbacks.onSwipe(deltaX > 0 ? 'right' : 'left', Math.abs(deltaX));
    }
    startX = startY = null;
  });
}

// 使用示例
const listItems = document.querySelectorAll('.list-item');
listItems.forEach(item => {
  bindSwipe(item, {
    onSwipe: (direction, distance) => {
      if (direction === 'left') showDeleteBtn(item);
      else showEditBtn(item);
    }
  });
});

進階優化技巧

  • CSS 協同動畫:使用 transform: translateX() + transition 實現按鈕滑出,避免 JS 頻繁操作 DOM 導致卡頓
  • 互斥機制:同一時刻只允許一個列表項展開,新滑動自動關閉舊項
  • 邊界處理:滑動超過按鈕寬度自動觸發操作(如直接刪除),提升效率
  • 無障礙支援:為鍵盤用戶提供 Enter/Space 觸發相同功能

避坑指南

  • touchmove 必須設 passive: false 才能調用 preventDefault() 阻止頁面滾動
  • iOS Safari 需在 <html> 加 touch-action: pan-y 允許垂直滾動
  • Android 部分機型 touchend 不觸發,需兼容 touchcancel
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved