在 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:设置为绝对定位,方便在页面中自由移动。通过以上代码,就可以实现绝对定位元素拖拽时不导致父页面滚动的效果。
网友回复


