Vue使用自定义指令实现按钮在区域内任意拖拽移动
项目场景
实现一个按钮,然后这个按钮可以在页面范围内,被拖拽到任意位置。
实现思路
- 实现父子两个div,并且设置需要拖拽的子元素为相对定位,其父元素为绝对定位
- 当鼠标按下(
onmousedown
)时,记录此时目标元素当前的left
和top
值 - 在鼠标移动(
onmousemove
)的过程中,计算每次移动的横向距离和纵向距离的变化值, - 然后实时并改变元素的
left
和top
值 - 最后,鼠标松开(
onmouseup
)时,子元素停留在当前位置,完成一次拖拽
实现效果
实现代码
<template>
<div>
<div class="draggable-box">
<div class="draggable-item" v-draggable>我可以移动哦!</div>
</div>
</div>
</template>
<script>
import draggable from '../../directive/test/draggable'
export default {
directives: {
draggable
},
data(){
return{
}
},
methods:{
}
}
</script>
<style lang="scss">
.draggable-box{
background-color: bisque;
position: relative;
border: 1px solid #333;
width: 500px;
height: 500px;
.draggable-item{
background-color: aqua;
position: absolute;
width: 50px;
height: 50px;
}
}
</style>
draggable.js文件如下:
const draggable = {
inserted: function (el) {
el.style.cursor = 'move'
el.onmousedown = function (e) {
console.log(el, e, 123)
let disx = e.pageX - el.offsetLeft
let disy = e.pageY - el.offsetTop
document.onmousemove = function (e) {
let x = e.pageX - disx
let y = e.pageY - disy
let maxX = document.body.clientWidth - parseInt(window.getComputedStyle(el).width)
let maxY = document.body.clientHeight - parseInt(window.getComputedStyle(el).height)
if (x < 0) {
x = 0
} else if (x > maxX) {
x = maxX
}
if (y < 0) {
y = 0
} else if (y > maxY) {
y = maxY
}
el.style.left = x + 'px'
el.style.top = y + 'px'
}
document.onmouseup = function () {
document.onmousemove = document.onmouseup = null
}
}
},
}
export default draggable
如有疑问,欢迎评论区留言。