如何在移动端实现左滑删除?

52 min read

左滑删除功能在移动端是一种常见的交互方式,下面是一个简单的示例代码。

首先,在 HTML 中创建一个包含列表项的容器:

<div id="list-container">
  <div class="list-item">Item 1</div>
  <div class="list-item">Item 2</div>
  <div class="list-item">Item 3</div>
  <div class="list-item">Item 4</div>
  <!-- ... -->
</div>

然后,在 JavaScript 中使用事件委托来处理用户左滑操作:

const listContainer = document.getElementById('list-container');
let startX, startY;

// 定义滑动处理函数
function handleSwipe(e) {
  const delBtnWidth = 60; // 删除按钮的宽度
  const touch = e.touches[0];
  const deltaX = touch.clientX - startX;
  const deltaY = touch.clientY - startY;

  if (Math.abs(deltaX) < Math.abs(deltaY)) return; // 不处理纵向滑动
  if (deltaX < -10) {
    // 用户左滑,显示删除按钮
    const listItem = e.target.closest('.list-item');
    const delBtn = document.createElement('div');
    delBtn.classList.add('del-btn');
    delBtn.innerText = '删除';
    delBtn.style.width = `${delBtnWidth}px`;
    listItem.appendChild(delBtn);
    listItem.style.transform = `translateX(-${delBtnWidth}px)`;
  } else if (deltaX > 10) {
    // 用户右滑,隐藏删除按钮
    const listItem = e.target.closest('.list-item');
    const delBtn = listItem.querySelector('.del-btn');
    if (delBtn) {
      delBtn.remove();
      listItem.style.transform = `translateX(0)`;
    }
  }
}

// 添加触摸事件处理函数
listContainer.addEventListener('touchstart', (e) => {
  startX = e.touches[0].clientX;
  startY = e.touches[0].clientY;
});

listContainer.addEventListener('touchmove', handleSwipe);

listContainer.addEventListener('touchend', (e) => {
  // 用户停止滑动,恢复状态
  const listItem = e.target.closest('.list-item');
  const delBtn = listItem.querySelector('.del-btn');
  if (delBtn && Math.abs(startX - e.changedTouches[0].clientX) < 10) {
    // 点击删除按钮
    listItem.remove();
  } else {
    listItem.style.transform = `translateX(0)`;
    setTimeout(() => {
      if (delBtn) delBtn.remove();
    }, 200);
  }
});

上述代码中,我们通过 touchstarttouchmovetouchend 事件来实现左滑删除功能。当用户左滑距离大于10像素时,我们在列表项的右侧添加一个删除按钮,并将列表项向左平移,以显示删除按钮。当用户右滑距离大于10像素时,我们隐藏删除按钮,还原列表项位置。如果用户在滑动过程中点击了删除按钮,我们直接删除对应的列表项。最后,使用 translateXtransform 来实现过渡效果。