Vue实现靠边可拖动悬浮球的代码,而且需要防止滚动屏幕导致悬浮球的抖动,吸附到屏幕边缘的时候,隐藏一半悬浮球
时间: 2023-08-06 12:04:57 浏览: 70
以下是Vue实现靠边可拖动悬浮球的代码:
```vue
<template>
<div class="float-ball" :class="{ 'hide': isHide }" ref="floatBall" @mousedown="startDrag">
<!-- 悬浮球内容 -->
</div>
</template>
<script>
export default {
data() {
return {
startX: 0, // 鼠标点击时的x轴位置
startY: 0, // 鼠标点击时的y轴位置
left: 0, // 悬浮球的左侧位置
top: 0, // 悬浮球的顶部位置
isDragging: false, // 是否正在拖拽中
isHide: false, // 是否隐藏
threshold: 50, // 悬浮球与边缘的距离阈值
screenWidth: 0, // 屏幕宽度
screenHeight: 0 // 屏幕高度
}
},
mounted() {
this.screenWidth = window.innerWidth
this.screenHeight = window.innerHeight
window.addEventListener('scroll', this.handleScroll, true)
},
beforeDestroy() {
window.removeEventListener('scroll', this.handleScroll, true)
},
methods: {
startDrag(e) {
this.startX = e.clientX
this.startY = e.clientY
this.isDragging = true
document.addEventListener('mousemove', this.doDrag)
document.addEventListener('mouseup', this.stopDrag)
},
doDrag(e) {
if (!this.isDragging) return
const newX = e.clientX
const newY = e.clientY
// 计算悬浮球的新位置
const newLeft = this.left + newX - this.startX
const newTop = this.top + newY - this.startY
// 防止悬浮球拖出屏幕边界
if (newLeft < 0) {
this.left = 0
} else if (newLeft > this.screenWidth - this.$refs.floatBall.offsetWidth) {
this.left = this.screenWidth - this.$refs.floatBall.offsetWidth
} else {
this.left = newLeft
}
if (newTop < 0) {
this.top = 0
} else if (newTop > this.screenHeight - this.$refs.floatBall.offsetHeight) {
this.top = this.screenHeight - this.$refs.floatBall.offsetHeight
} else {
this.top = newTop
}
// 防止悬浮球随着滚动屏幕抖动
if (document.documentElement.scrollTop > 0) {
this.top -= document.documentElement.scrollTop
}
// 判断是否靠近屏幕边缘
if (this.left < this.threshold || this.left > this.screenWidth - this.$refs.floatBall.offsetWidth + this.threshold) {
this.hideBall()
} else {
this.showBall()
}
},
stopDrag() {
this.isDragging = false
document.removeEventListener('mousemove', this.doDrag)
document.removeEventListener('mouseup', this.stopDrag)
},
handleScroll() {
if (!this.isHide) {
this.top -= document.documentElement.scrollTop
}
},
hideBall() {
this.isHide = true
if (this.left < this.threshold) {
this.left = -this.$refs.floatBall.offsetWidth / 2
} else {
this.left = this.screenWidth - this.$refs.floatBall.offsetWidth / 2
}
},
showBall() {
this.isHide = false
if (this.left < this.threshold) {
this.left = -this.$refs.floatBall.offsetWidth / 2 + this.threshold
} else {
this.left = this.screenWidth - this.$refs.floatBall.offsetWidth / 2 - this.threshold
}
}
}
}
</script>
<style scoped>
.float-ball {
position: fixed;
z-index: 999;
width: 60px;
height: 60px;
border-radius: 50%;
background-color: #f00;
cursor: move;
/* 悬浮球样式 */
}
.hide {
transform: translateX(-50%);
/* 隐藏悬浮球一半 */
}
</style>
```
需要注意的是,为了防止悬浮球随着滚动屏幕抖动,我们需要在 `doDrag` 和 `handleScroll` 方法中将悬浮球的 `top` 值减去滚动的距离。此外,当悬浮球靠近屏幕边缘时,我们需要将其隐藏一半,可以通过设置 `transform: translateX(-50%)` 实现。