适配双端浮标拖拽
最近写到一个需求是悬浮球拖动,看了很多网上的案例,要么移动端很流畅那么PC端就很卡,要么双端(ps:双端是指移动端和PC端)都很卡。于是自己就在网上百度改造了一款双端基本上很流畅的就能拖拽
首先先写一个div壳子(拖拽就是改变这个div的位置)
<div
class="box-new"
v-show="boxnew"
v-drag
@click="onBtnClicked"
ref="floatButton"
:style="{'width': itemWidth + 'px', 'height': itemHeight + 'px', 'left': left + 'px', 'top': top + 'px'}"
>
<img src="img/xuanfuqiu.png" draggable="false" />
</div>
这里面的 v-drag 主要是用于移动端
之后就要去注册一下事件(因为我是在html中引入的vue.js所以我的data中没有写return 如果大家是在vue项目的话记得请在return中写哦~~)
data: {
boxnew: true,
bindicon: true,
//浮标拖动
clientWidth: 0,
clientHeight: 0,
timer: null,
currentTop: 0,
left: 90,
top: 0,
activeArr: "GiftBags",
},
directives: {
drag: { // 在要拖拽的元素上加 v-drag
// 指令的定义
bind: function (el) {
let odiv = el //获取当前元素
odiv.onmousedown = function (e) {
//算出鼠标相对元素的位置
let startX = e.clientX;
let startY = e.clientY;
let starL = odiv.offsetLeft
let starT = odiv.offsetTop
let maxLeft = document.documentElement.offsetWidth - odiv.offsetWidth;
starL = starL > maxLeft ? maxLeft : starL;
document.onmousemove = function (e) {
odiv.style.transition = 'none';
// 元素的位置
let left = e.clientX - startX + starL;
let top = e.clientY - startY + starT;
// 边界判断
let maxLeft = document.documentElement.offsetWidth;
let minLeft = 0;
left = left > maxLeft ? maxLeft : left;
left = left < minLeft ? minLeft : left;
//绑定元素位置到positionX和positionY上面
this.positionX = top
this.positionY = left
//移动当前元素
odiv.style.left = left + 'px'
odiv.style.top = top + 'px'
}
document.onmouseup = () => {
let boxLeft = parseInt(odiv.style.left),
pageX = document.documentElement.offsetWidth - odiv.offsetWidth;
document.onmousemove = null
document.onmouseup = null
// 悬浮左右滑动的逻辑
if (boxLeft < pageX / 2) {
odiv.style.left = 0 + 'px';
odiv.style.transition = 'left .3s';
} else {
odiv.style.left = pageX + 'px';
odiv.style.transition = 'left .3s';
}
}
}
},
},
},
props: {
itemWidth: {
// 悬浮按钮宽度
type: Number,
default: 50
},
itemHeight: {
// 悬浮按钮高度
type: Number,
default: 50
},
gapWidth: {
// 距离左右两边距离
type: Number,
default: -25
},
coefficientHeight: {
// 从上到下距离比例
type: Number,
default: 0.1
}
},
后面我们就需要去做一些拖拽的操作啦,这些操作可都得写在methods下面哦
onBtnClicked() {
this.$emit("onFloatBtnClicked");
},
handleScrollStart() {
this.timer && clearTimeout(this.timer);
this.timer = setTimeout(() => {
this.handleScrollEnd();
}, 300);
this.currentTop =
document.documentElement.scrollTop || document.body.scrollTop;
if (this.left > this.clientWidth / 2) {
this.left = this.clientWidth - this.itemWidth / 2;
} else {
this.left = -this.itemWidth / 2;
}
},
handleScrollEnd() {
let scrollTop =
document.documentElement.scrollTop || document.body.scrollTop;
if (scrollTop === this.currentTop) {
if (this.left > this.clientWidth / 2) {
this.left = this.clientWidth - this.itemWidth - this.gapWidth;
} else {
this.left = this.gapWidth;
}
}
},
最后我在mounted里面做了一个判断是pc然后再确定悬浮球的边距
mounted() {
// 判断Pc端
if (document.documentElement.clientWidth > 750) {
this.$refs.floatButton.vue = this; // 将实例传递给当前元素
}
//移动端拖拽
this.clientWidth = document.documentElement.clientWidth;
this.clientHeight = document.documentElement.clientHeight;
this.left = this.clientWidth - this.itemWidth - this.gapWidth;
this.top = this.clientHeight * this.coefficientHeight;
this.$nextTick(() => {
const floatButton = this.$refs.floatButton;
floatButton.addEventListener("touchstart", () => {
floatButton.style.transition = "none";
});
// 在拖拽的过程中,组件应该跟随手指的移动而移动。
floatButton.addEventListener("touchmove", e => {
console.log("移动中", e);
if (e.targetTouches.length === 1) {
// 一根手指
let touch = e.targetTouches[0];
this.left = touch.clientX - 40;
this.top = touch.clientY - 25;
}
});
// 拖拽结束以后,重新调整组件的位置并重新设置过度动画。
floatButton.addEventListener("touchend", () => {
floatButton.style.transition = "all 0.3s";
if (this.left > document.documentElement.clientWidth / 2) {
this.left = document.documentElement.clientWidth - 20;
} else {
this.left = -20;
}
});
});
},
到这,,,,悬浮球拖拽的操作就完成了,如果大家有需要的话完全拿代码去试一试哦,最后谢谢大家的采纳,如果有什么更好的方法欢迎联系,谢谢大家~~
版权声明:本文为weixin_48119454原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。