<template>
<div class="drag-ball" ref="dragBall" @mousedown.stop.prevent="mousedown" @mouseup.stop.prevent="mouseup">
<div class="drag-content">
<slot name="value">{{ value }}</slot>
</div>
</div>
</template>
<script>
export default {
name: 'drag-ball',
props: {
value: {
type: String,
default: '悬浮球!'
}
},
data() {
return {
canDrag: false,
// 偏移
inset: {
left: 0,
top: 0
},
// 移动
move: {},
// 位置
position: {
left: 0,
top: 0
},
// 初始位置
positionOld: {},
startTime: null,
endTime: null
};
},
methods: {
toNew() {
alert('去新版');
},
mousedown(e) {
if (!this.canDrag) {
this.startTime = e.timeStamp;
this.positionOld = this.getPosition(this.dragBall);
this.position = {
left: this.positionOld.left,
top: this.positionOld.top
//...this.positionOld
};
console.log(this.position);
console.log(e.clientX, e.clientY);
this.inset = {
left: e.clientX - this.positionOld.left,
top: e.clientY - this.positionOld.top
};
this.canDrag = true;
}
if (e.preventDefault) {
e.preventDefault();
} else{
e.returnValue=false;
};
const _this = this
document.onmousemove=function (e) {
if (_this.canDrag) {
let left = e.clientX - _this.inset.left;
let top = e.clientY - _this.inset.top;
if (left < 0) {
left = 0;
} else if (left > (window.innerWidth - _this.dragBall.offsetWidth)) {
left = window.innerWidth - _this.dragBall.offsetWidth;
}
if (top < 0) {
top = 0;
} else if (top > (window.innerHeight - _this.dragBall.offsetHeight)) {
top = window.innerHeight - _this.dragBall.offsetHeight;
}
_this.dragBall.style.left = left + 'px';
_this.dragBall.style.top = top + 'px';
_this.move = {
x: left - _this.positionOld.left,
y: top - _this.positionOld.top
};
_this.position = {
left,
top
};
}
}
},
mouseup(e) {
if (this.canDrag) {
this.endTime = e.timeStamp;
if (this.endTime - this.startTime > 100 || Math.abs(this.move.x) > 2 || Math.abs(this.move.y) > 2) {
// 非单击事件
if ((this.position.left + this.dragBall.offsetWidth / 2) > window.innerWidth / 2) {
this.dragBall.style.left = window.innerWidth - this.dragBall.offsetWidth + 'px';
} else {
this.dragBall.style.left = 0 + 'px';
}
} else {
this.$emit('click');
}
this.inset = {};
this.move = {};
this.position = {};
this.canDrag = false;
}
},
// 获取dom的绝对位置
getPosition(source) {
let left = source.offsetLeft; //获取元素相对于其父元素的left值var left
let top = source.offsetTop;
let current = source.offsetParent; // 取得元素的offsetParent // 一直循环直到根元素
while (current != null) {
left += current.offsetLeft;
top += current.offsetTop;
current = current.offsetParent;
}
return {
left: left,
top: top
};
}
},
computed: {
dragBall() {
console.log(this.$refs.dragBall)
return this.$refs.dragBall;
}
}
};
</script>
<style scoped>
.drag-ball {
position: fixed;
z-index: 10003;
right: 0;
top: 70%;
width: 5em;
height: 5em;
background: deepskyblue;
border-radius: 50%;
overflow: hidden;
box-shadow: 0px 0px 10px 2px skyblue;
display: flex;
align-items: center;
justify-content: center;
padding: 1em;
user-select: none;
}
.drag-ball .drag-content {
overflow-wrap: break-word;
font-size: 14px;
color: #fff;
letter-spacing: 2px;
}
</style>
直接mousemove的话 会发生移动卡顿。

浙公网安备 33010602011771号