You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

移动端如何实现长按元素后才禁止页面滚动?

实现长按拖拽时禁止页面滚动,未长按则允许滚动的解决方案

需求说明

用户触摸并长按指定元素后可拖拽,拖拽期间禁止页面滚动;若未长按足够时间(1秒)就触发拖拽,页面保持正常滚动。

期望行为

  • ✅ 长按1秒后拖拽,页面无滚动
  • ✅ 未长按1秒,页面正常滚动
  • ✅ 触摸非拖拽元素时,页面正常滚动

不期望行为

  • ❌ 长按1秒后仍能滚动页面
  • ❌ 未长按就拖拽时,页面滚动被禁止

当前问题与尝试方案

现有代码存在长按1秒后仍可滚动页面的问题,已尝试以下方案但未解决:

  1. 在touchstart事件处理器中调用event.preventDefault():提前禁止页面滚动,不符合需求
  2. 存储touchstart事件以便长按后调用event.preventDefault():无效
  3. touchstart时临时禁用页面滚动,未长按则恢复:无法阻止下拉刷新等浏览器原生滚动特性,需要类似event.preventDefault()的有效方案

解决方案

核心思路是通过定时器判断是否触发长按,仅在长按生效后才在touchmove中阻止页面滚动,具体实现代码如下:

<div class="draggable">可长按拖拽的元素</div>
<div>普通元素,触摸可正常滚动</div>

<style>
.draggable {
  width: 200px;
  height: 200px;
  background: #42b983;
  color: white;
  text-align: center;
  line-height: 200px;
  position: absolute;
}
body {
  height: 2000px;
}
</style>

<script>
const draggableEl = document.querySelector('.draggable');
let longPressTimer = null;
let isDraggableEnabled = false;
let startX, startY;

// 触摸开始:启动长按定时器
draggableEl.addEventListener('touchstart', (e) => {
  startX = e.touches[0].clientX;
  startY = e.touches[0].clientY;
  longPressTimer = setTimeout(() => {
    isDraggableEnabled = true;
  }, 1000);
});

// 触摸移动:仅长按生效后阻止滚动并执行拖拽
draggableEl.addEventListener('touchmove', (e) => {
  if (!isDraggableEnabled) return;
  
  e.preventDefault(); // 阻止页面滚动
  
  // 更新拖拽元素位置
  const dx = e.touches[0].clientX - startX;
  const dy = e.touches[0].clientY - startY;
  draggableEl.style.left = `${parseInt(draggableEl.style.left || 0) + dx}px`;
  draggableEl.style.top = `${parseInt(draggableEl.style.top || 0) + dy}px`;
  startX = e.touches[0].clientX;
  startY = e.touches[0].clientY;
});

// 触摸结束/取消:重置状态
['touchend', 'touchcancel'].forEach(eventType => {
  draggableEl.addEventListener(eventType, () => {
    clearTimeout(longPressTimer);
    isDraggableEnabled = false;
  });
});
</script>

代码关键点说明

  • 长按判断:通过setTimeout设置1秒延迟,触发后标记拖拽状态为激活
  • 滚动控制:仅在拖拽状态激活时,在touchmove中调用e.preventDefault(),精准阻止页面滚动,避免提前禁用
  • 状态重置:触摸结束或取消时清除定时器、重置拖拽状态,确保未长按的情况下页面滚动不受影响
  • 元素区分:仅对指定的.draggable元素绑定事件,触摸其他元素时页面保持正常滚动

内容的提问来源于stack exchange,提问作者Joshua F

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 06:45:09