1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > vue自定义v-drag指令实现鼠标拖拽

vue自定义v-drag指令实现鼠标拖拽

时间:2024-02-18 11:18:26

相关推荐

vue自定义v-drag指令实现鼠标拖拽

vue自定义v-drag指令实现鼠标拖拽

1. 效果2. 相关概念3. 实现思路4. 代码

1. 效果

使用自定义拖拽指令v-drag来实现鼠标拖拽的效果。

2. 相关概念

Element.clientWidth:元素可视宽度(不包含滚动条)。Element.clientHeight:元素可视高度(不包含滚动条)。MouseEvent.clientX:鼠标相对于浏览器左上顶点的水平坐标(不包含滚动条),与之对应的MouseEvent.pageX:相对于整个文档的水平坐标(即包含滚动)。MouseEvent.clientY:鼠标相对于浏览器左上顶点的垂直坐标(不包含滚动条),与之对应的MouseEvent.pageY:相对于整个文档的垂直坐标(即包含滚动)。HTMLElement.offsetLeft:当前元素左上角相对于父节点(HTMLElement.offsetParent)的左边偏移的距离。HTMLElement.offsetTop:当前元素左上角相对于父节点(HTMLElement.offsetParent)的顶部偏移的距离。

3. 实现思路

自定义拖拽指令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的监听事件,否则会一直执行。

4. 代码

在组件中使用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>

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。