浮动菜单可移动
<template>
<transition>
<div
v-if="isFloatball"
ref="dragIcon"
:style="{left: left + 'px',top: top + 'px',width: itemWidth + 'px',height: itemHeight + 'px'}"
class="dragIcon"
@click="goHome"
@touchstart.stop="handleTouchStart"
@touchmove.prevent.stop="handleTouchMove($event)"
@touchend.stop="handleTouchEnd"
>
<div class="iconCont">
<van-icon name="contact" color="#fff" size="20px"/>
<span>我的</span>
</div>
</div>
</transition>
</template>
<script>
export default {
props: {
id: {
type: Number,
default: null
},
itemWidth: {
type: Number,
default: 50
},
itemHeight: {
type: Number,
default: 50
}
},
data() {
return {
left: 0,
top: 0,
startToMove: false,
isFloatball: true,
timer: null,
currentTop: null,
clientW: document.documentElement.clientWidth, // 视口宽
clientH: document.documentElement.clientHeight // 视口高
}
},
created() {
this.type = JSON.parse(localStorage.getItem('type'))
if (this.type === 1) {
this.isFloatball = false
} else {
this.isFloatball = true
}
var left = JSON.parse(localStorage.getItem('left'))
var top = JSON.parse(localStorage.getItem('top'))
if (left) {
this.left = left
this.top = top
} else {
this.left = (this.clientW - this.itemWidth - 30)
this.top = (this.clientH / 2 - this.itemHeight / 2) + 160
}
},
mounted() {
this.bindScrollEvent()
},
beforeDestroy() {
// 记得销毁一些全局的的事件
this.removeScrollEvent()
},
methods: {
goHome() {
// 点击Icon要跳转的路径,
this.$router.push({
path: '/mine',
query: {
id: this.id
}
})
},
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.left = 30// 不让贴边 所以设置30没设置0
this.handleIconY()
} else {
this.left = this.clientW - this.itemWidth - 30// 不让贴边 所以减30
this.handleIconY()
}
this.$refs.dragIcon.style.transition = 'all .3s'
localStorage.setItem('left', JSON.stringify(this.left))
},
handleIconY() {
if (this.top < 0) {
this.top = 30// 不上帖上边所以设置为30 没设置0
} else if (this.top + this.itemHeight > this.clientH) {
this.top = this.clientH - this.itemHeight - 30// 不让帖下边所以减30
}
localStorage.setItem('top', JSON.stringify(this.top))
},
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
}
}
}
}
</script>
<style scoped lang="less">
.dragIcon {
position: fixed;
width: 40px;
height: 40px;
border-radius: 50%;
background: #ea5520;
text-align: center;
color: #fff;
z-index: 98;
box-shadow: 0px 1px 2px 0px rgba(248, 84, 25, 0.938);
opacity: .9;
.iconCont{
padding: 5px;
display: flex;
justify-content: center;
align-items: center;
flex-wrap: wrap;
span{
font-size: 12px;
}
}
}
.v-enter {
opacity: 1;
}
.v-leave-to {
opacity: 0;
}
.v-enter-active,
.v-leave-active {
transition: opacity 0.3s;
}
</style>