1.第一种写法
<template>
<div
class="tool"
@touchstart="start"
@touchmove.prevent="move"
@touchend="end"
ref="dragRef"
@click="check"
ondrag="drag"
:style="dragStyle"
>
{{ text }}
</div>
</template>
<script>
export default {
props: {
text: {
type: String,
default: ""
},
// 可移动边界限制
boundary: {
type: Object,
default: () => ({
leftOrTop: 20,
rightOrBottom: 70
})
},
// 自定义样式
dragStyle: {
type: Object,
default: () => ({
right: "20px",
top: "70%",
width: "3.2em"
})
}
},
data() {
return {
position: { x: 0, y: 0 },
nx: "",
ny: "",
dx: "",
dy: "",
xPum: "",
yPum: ""
};
},
methods: {
check() {
this.$emit("check");
},
start(event) {
var touch;
touch = event.touches[0];
this.position.x = touch.clientX;
this.position.y = touch.clientY;
this.dx = this.$refs.dragRef.offsetLeft;
this.dy = this.$refs.dragRef.offsetTop;
},
// 拖起来~~~~
move(event) {
var touch;
touch = event.touches[0];
this.nx = touch.clientX - this.position.x;
this.ny = touch.clientY - this.position.y;
this.xPum = this.dx + this.nx;
this.yPum = this.dy + this.ny;
this.$refs.dragRef.style.left = this.xPum + "px";
this.$refs.dragRef.style.top = this.yPum + "px";
if (this.xPum <= this.boundary.leftOrTop) {
this.$refs.dragRef.style.left = this.boundary.leftOrTop + "px";
} else if (
this.xPum >
event.view.innerWidth - this.boundary.rightOrBottom
) {
this.$refs.dragRef.style.left =
event.view.innerWidth - this.boundary.rightOrBottom + "px";
}
if (this.yPum <= this.boundary.leftOrTop) {
this.$refs.dragRef.style.top = this.boundary.leftOrTop + "px";
} else if (
this.yPum >
event.view.innerHeight - this.boundary.rightOrBottom
) {
this.$refs.dragRef.style.top =
event.view.innerHeight - this.boundary.rightOrBottom + "px";
}
document.addEventListener(
"touchmove",
function(event) {
event.stopPropagation();
},
false
);
},
end(event) {}
}
};
</script>
<style lang="less" scoped>
.tool {
position: fixed;
text-align: center;
background: #eef5ff;
border-radius: 50%;
padding: 7px;
box-sizing: content-box;
font-size: 12px;
color: #247cfc;
box-shadow: 0px 2px 9px #9197a1;
touch-callout: none;
z-index: 99;
}
</style>
2.第二种直接用 参数可根据需求传值
<template>
<!-- 子组件 -->
<div class="float_button">
<div
@click="onBtnClicked"
ref="floatButton"
class="float_info"
:style="{'width': itemWidth + 'px','margin':'5px 10px', 'height': itemHeight + 'px', 'left': left + 'px', 'top': top + 'px'}"
>
<img src="../assets/proudect/productList.png" alt="">
</div>
</div>
</template>
<script>
export default {
data() {
return {
clientWidth: 0,
clientHeight: 0,
timer: null,
currentTop: 0,
left: 0,
top: 0,
itemWidth: 60 , //按钮宽度
isShort: true,
itemHeight: 70, // 悬浮按钮高度
gapWidth: 0, // 距离左右两边距离
coefficientHeight: 0.6, // 从上到下距离比例
}
},
created() {
// console.log('屏幕宽度', document.documentElement.clientWidth)
// console.log('屏幕高度度', document.documentElement.clientHeight)
this.clientWidth = document.documentElement.clientWidth
this.clientHeight = document.documentElement.clientHeight
this.left = this.clientWidth - this.itemWidth - this.gapWidth - 20;
this.top = this.clientHeight * this.coefficientHeight - 200
},
methods: {
onBtnClicked() {
this.$emit('onBtnClicked')
},
},
mounted() {
this.$nextTick(() => {
const floatButton = this.$refs.floatButton
floatButton.addEventListener("touchstart", () => {
floatButton.style.transition = 'none'
})
// 在拖拽的过程中,组件应该跟随手指的移动而移动。
floatButton.addEventListener("touchmove", (e) => {
if (e.targetTouches.length === 1) { // 一根手指
document.body.addEventListener('touchmove', this.bodyScroll, { passive: false }); //禁止页面滑动
let touch = e.targetTouches[0]
this.left = touch.clientX - 20
this.top = touch.clientY - 25
}
})
// 拖拽结束以后,重新调整组件的位置并重新设置过度动画。
floatButton.addEventListener("touchend", () => {
floatButton.style.transition = 'all 0.3s'
console.log('拖拽结束后left', this.left)
document.body.removeEventListener('touchmove', this.bodyScroll, { passive: false }); //解除页面禁止滑动
if (this.left > document.documentElement.clientWidth - 70) {
this.left = document.documentElement.clientWidth - 70;
}
if (this.left < 0) {
this.left = 0
}
if(this.top > document.documentElement.clientHeight - 60){
this.top = document.documentElement.clientHeight - 60;
}
if (this.top < 0) {
this.top = 0
}
})
})
},
beforeDestroy() {
// 添加监听页面滚动
window.removeEventListener('scroll', this.handleScrollStart)
},
}
</script>
<style lang="less" scoped>
.float_button {
z-index: 999;
.float_info {
z-index: 99;
transition: all 0.3s;
position: fixed;
bottom: 436px;
right: 0;
margin: 5px 10px;
display: flex;
flex-flow: row;
justify-content: center;
align-items: center;
// background: #1666ca;
// background-color: rgba(22, 102, 202, 0.6);
// border-radius: 10px;
cursor: pointer;
img{
width: 100%;
height: 100%;
}
}
}
</style>