+
78
-

vue在手机端上下拖拽元素的时候如何禁止父元素及body的滚动导致无法拖拽完成?

vue在手机端上下拖拽元素的时候如何禁止父元素及body的滚动导致无法拖拽完成?

body有滚动条,但是元素拖拽的行为导致滚动条上下滑动无法完成子元素拖拽怎么解决?

网友回复

+
27
-

下面我将为您提供几种在 Vue 中实现的解决方案,从最推荐到备选方案,并附上完整的代码示例。

解决方案 1: 使用事件修饰符 .prevent (最推荐)

Vue 的事件修饰符提供了一种非常优雅和声明式的方式来处理这个问题。.prevent 修饰符会自动调用 event.preventDefault()。

关键点: 将 .prevent 添加到 @touchmove 事件上。现代浏览器为了优化滚动性能,会将 touchmove 事件默认为“被动 (passive)”,这意味着在事件监听器内部调用 event.preventDefault() 可能会被忽略。而 Vue 的 .prevent 修饰符会自动处理这个问题,确保 preventDefault 生效。

完整 Vue 3 (Composition API) 示例

这是一个完整的、可直接运行的组件示例。

<template>
  <div class="page-container">
    <div class="content">
      <p>向上滚动页面查看效果</p>
      <p>...</p>
      <p>...</p>
      <p>尝试拖动下面的方块</p>

      <!-- Draggable Element -->
      <div 
        class="draggable-box"
        :style="boxStyle"
        @touchstart.stop="onTouchStart"
        @touchmove.prevent="onTouchMove"
        @touchend="onTouchEnd"
      >
        拖动我
      </div>

      <p>...</p>
      <p>...</p>
      <p>页面底部</p>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, computed } from 'vue';

// 标记当前是否正在拖拽
const isDragging = ref(false);

// 元素的位置
const position = reactive({ x: 0, y: 0 });

// 拖拽起始时,手指相对于元素左上角的偏移
const startOffset = reactive({ x: 0, y: 0 });

// 使用计算属性动态生成样式
const boxStyle = computed(() => ({
  transform: `translate(${position.x}px, ${position.y}px)`
}));

// 触摸开始事件
const onTouchStart = (event) => {
  isDragging.value = true;

  // 记录初始触摸点与元素当前位置的差值
  const touch = event.touches[0];
  startOffset.x = touch.clientX - position.x;
  startOffset.y = touch.clientY - position.y;

  console.log("Drag Start");
};

// 触摸移动事件
const onTouchMove = (event) => {
  // 如果没有在拖拽...

点击查看剩余70%

我知道答案,我要回答