vue自定义v-drag指令实现鼠标拖拽
使用自定义指令v-drag实现鼠标拖拽功能。鼠标按下时获取获取鼠标在元素上的位置,每次移动时不断计算和设置元素左上顶点坐标位置,并且在鼠标松开时要禁用掉down的监听事件,否则会一直执行。知道了鼠标的相对位置,后续的鼠标移动,只要知道移动后的鼠标坐标,就能很容易的把当前位置元素的左上顶点坐标算出来。在组件中使用directives注册一个自定义拖拽指令v-drag,在想要拖动的元素上使用“v-dr
前言
大家好,我是南木元元,热衷分享有趣实用的文章。本文来分享一下如何在vue中通过自定义指令的方式来实现鼠标拖拽的效果。
实现效果
实现效果就是鼠标按下蓝色区域的图形后,就能够进行元素的拖拽。
浏览器坐标属性
在介绍自定义指令之前,首先需要知道浏览器中常用的一些坐标属性。
- Element.clientWidth:元素可视宽度(不包含滚动条)。
- Element.clientHeight:元素可视高度(不包含滚动条)。
- MouseEvent.clientX:鼠标相对于浏览器左上顶点的水平坐标(不包含滚动条),与之对应的MouseEvent.pageX:相对于整个文档的水平坐标(即包含滚动)。
- MouseEvent.clientY:鼠标相对于浏览器左上顶点的垂直坐标(不包含滚动条),与之对应的MouseEvent.pageY:相对于整个文档的垂直坐标(即包含滚动)。
- HTMLElement.offsetLeft:当前元素左上角相对于父节点(HTMLElement.offsetParent)的左边偏移的距离。
- HTMLElement.offsetTop:当前元素左上角相对于父节点(HTMLElement.offsetParent)的顶部偏移的距离。
实现思路
接下来就可以自定义拖拽指令v-drag了。
首先给需要拖拽的元素设置 position: fixed或者position:absolute定位,使得当前元素的位置是相对于浏览器左上顶点的位置。这里注意区分Position的几个属性值:
- Absolute:绝对定位,是相对于最近的且不是static定位的父元素来定位。
- Fixed:绝对定位,是相对于浏览器窗口来定位的,是固定的,不会跟屏幕一起滚动。
- Relative:相对定位,是相对于其原本的位置来定位的。
- Relative:相对定位,是相对于其原本的位置来定位的。
元素的位置是通过调整左上顶点坐标来的,所以我们要知道元素拖拽后的左上顶点坐标,这样才能将元素移动到指定位置。
计算出鼠标在移动元素前在元素上的位置 :
let disX = e.clientX - el.offsetLeft;
let disY = e.clientY - el.offsetTop;
知道了鼠标的相对位置,后续的鼠标移动,只要知道移动后的鼠标坐标,就能很容易的把当前位置元素的左上顶点坐标算出来。
计算元素移动后的左上顶点坐标:
el.style.left = e.clientX - disX + "px"; //设置定位元素的左部位置
el.style.top = e.clientY - disY + "px"; //设置定位元素的顶部位置
总体流程:鼠标按下时获取获取鼠标在元素上的位置,每次移动时不断计算和设置元素左上顶点坐标位置,并且在鼠标松开时要禁用掉down的监听事件,否则会一直执行。
实现代码
在组件中使用directives注册一个自定义拖拽指令v-drag,在想要拖动的元素上使用“v-drag”即可。实现代码如下:
<template>
<div class="box" v-drag></div>
</template>
<script>
export default {
//注册局部自定义指令
directives: {
//el:指令所绑定的元素
drag(el, bindings) {
//鼠标按下事件
el.onmousedown = function(e) {
// 获取鼠标在元素上的位置
let disX = e.clientX - el.offsetLeft;
let disY = e.clientY - el.offsetTop;
//鼠标移动事件
document.onmousemove = function(e) {
el.style.left = e.clientX - disX + "px"; //设置定位元素的左部位置
el.style.top = e.clientY - disY + "px"; //设置定位元素的顶部位置
};
//鼠标松开事件
document.onmouseup = function() {
//要禁用掉down的监听事件,否则会一直执行
document.onmousemove = document.onmouseup = null;
};
};
},
},
};
</script>
<style scoped>
.box {
width: 300px;
height: 300px;
background-color: cyan;
position: fixed;
left: 100px;
top: 100px;
}
</style>
结语
🔥如果此文对你有帮助的话,欢迎💗关注、👍点赞、⭐收藏、✍️评论,支持一下博主~
更多推荐
所有评论(0)