<transition>
<div
ref="dragIcon"
class="dragIcon"
@touchstart.stop="handleTouchStart"
@touchmove.prevent.stop="handleTouchMove($event)"
@touchend.stop="handleTouchEnd"
:style="{ left: left + 'px', top: top + 'px', width: itemWidth + 'px',height: itemHeight + 'px', lineHeight: itemHeight + 'px' }"
v-if="isShow"
>
<van-icon size="30" name="audio" />
</div>
</transition>
data() {
return {
itemWidth: '50', // 悬浮点宽度
itemHeight: '50', // 悬浮点高度
left: 0, // 悬浮点位置
top: 0, // 悬浮点位置
startToMove: false,
timer: null,
currentTop: null,
clientW: document.documentElement.clientWidth, // 视口宽
clientH: document.documentElement.clientHeight // 视口高
}
},
created() {
this.left = this.clientW - this.itemWidth
this.top = this.clientH / 2 - this.itemHeight / 2
},
mounted() {
// 监听滚动事件
this.bindScrollEvent()
},
beforeDestroy() {
// 记得销毁一些全局的的事件
this.removeScrollEvent()
},
methods:{
handleTouchStart() {
this.startToMove = true
this.$refs.dragIcon.style.transition = 'none'
},
handleTouchMove(e) {
const clientX = e.targetTouches[0].clientX // 手指相对视口的x
const clientY = e.targetTouches[0].clientY // 手指相对视口的y
const isInScreen = clientX <= this.clientW && clientX >= 0 && clientY <= this.clientH && clientY >= 0
if (this.startToMove && e.targetTouches.length === 1) {
if (isInScreen) {
this.left = clientX - this.itemWidth / 2
this.top = clientY - this.itemHeight / 2
}
}
},
handleTouchEnd() {
if (this.left < this.clientW / 2) {
this.handleIconY()
this.handleIconX()
} else {
this.handleIconX()
this.handleIconY()
}
this.$refs.dragIcon.style.transition = 'all .3s'
},
handleIconY() {
if (this.top < 0) {
this.top = 0
} else if (this.top > this.clientH - this.itemHeight) {
this.top = this.clientH - this.itemHeight
}
},
handleIconX() {
if (this.left < 0) {
this.left = 0
} else if (this.left > this.clientW - this.itemWidth) {
this.left = this.clientW - this.itemWidth
}
},
bindScrollEvent() {
window.addEventListener('scroll', this.handleScrollStart)
},
removeScrollEvent() {
window.removeEventListener('scroll', this.handleScrollStart)
},
handleScrollStart() {
this.isShow = false
this.timer && clearTimeout(this.timer)
this.timer = setTimeout(() => {
this.handleScrollEnd()
}, 300)
this.currentTop = document.documentElement.scrollTop || document.body.scrollTop
},
handleScrollEnd() {
this.scrollTop = document.documentElement.scrollTop || document.body.scrollTop
// 判断是否停止滚动的条件
if (this.scrollTop === this.currentTop) {
this.isShow = true
}
},
}
.dragIcon {
position: fixed;
border-radius: 50%;
background-color: rgba($color: #333, $alpha: 0.6);
line-height: 40px;
text-align: center;
color: #fff;
z-index: 100;
width: 40px;
height: 40px;
}