在 UniApp 中,要实现绝对定位元素拖拽时不导致父页面滚动,可以通过阻止触摸事件的默认行为来实现。以下是详细的实现步骤和示例代码:
实现思路绝对定位元素:将需要拖拽的元素设置为绝对定位,方便在页面中自由移动。绑定触摸事件:为元素绑定 touchstart、touchmove 和 touchend 事件,用于处理拖拽操作。阻止默认行为:在 touchmove 事件中,调用 event.preventDefault() 方法阻止页面滚动。示例代码页面结构(.vue 文件)<template> <view class="container"> <!-- 父页面内容 --> <view class="parent-content"> <view v-for="i in 50" :key="i">{{ i }}</view> </view> <!-- 可拖拽的绝对定位元素 --> <view class="draggable-element" :style="{ left: dragX + 'px', top: dragY + 'px' }" @touchstart="onTouchStart" @touchmove="onTouchMove" @touchend="onTouchEnd" > 可拖拽元素 </view> </view> </template> <script> export default { data() { return { startX: 0, startY: 0, dragX: 100, // 初始 x 坐标 dragY: 100, // 初始 y 坐标 offsetX: 0, offsetY: 0 }; }, methods: { onTouchStart(event) { // 记录触摸开始时的坐标 this.startX = event.changedTouches[0].clientX; this.startY = event.changedTouches[0].clientY; this.offsetX = this.dragX; this.offsetY = this.dragY; }, onTouchMove(event) { // 阻止默认的滚动行为 event.preventDefault(); // 计算移动的距离 const currentX = event.changedTouches[0].clientX; const currentY = event.changedTouches[0].clientY; const dx = currentX - this.startX; const dy = currentY - this.startY; // 更新元素的位置 this.dragX = this.offsetX + dx; this.dragY = this.offsetY + dy; }, onTouchEnd() { // 触摸结束,可添加额外逻辑,如边界处理等 } } }; </script> <style scoped> .container { position: relative; height: 100vh; overflow: auto; } .parent-content { height: 2000px; /* 模拟长内容 */ } .draggable-element { position: absolute; width: 100px; height: 100px; background-color: #007aff; color: white; text-align: center; line-height: 100px; cursor: pointer; } </style>代码解释
HTML 部分:
<view class="parent-content">:模拟父页面的长内容,用于测试滚动效果。<view class="draggable-element">:可拖拽的绝对定位元素,通过 :style 绑定 dragX 和 dragY 来动态更新其位置。JavaScript 部分:
onTouchStart 方法:记录触摸开始时的坐标和元素的初始位置。onTouchMove 方法:event.preventDefault():阻止默认的滚动行为,确保拖拽元素时父页面不会滚动。计算触摸移动的距离,并更新元素的位置。onTouchEnd 方法:触摸结束时可添加额外的逻辑,如边界处理等。CSS 部分:
.container:设置为相对定位,作为可拖拽元素的定位参考。.draggable-element:设置为绝对定位,方便在页面中自由移动。通过以上代码,就可以实现绝对定位元素拖拽时不导致父页面滚动的效果。
网友回复