Vue 自定义拖拽指令(在 main.js 文件写入以下代码)
Vue.directive('drag', function (el) {
const oDiv = el // 当前元素
document.onselectstart = () => {
return false
}
oDiv.onmousedown = e => { // 鼠标按下时的鼠标所在的X,Y坐标
// 鼠标按下,计算当前元素距离可视区的距离
const disX = e.clientX - oDiv.offsetLeft
const disY = e.clientY - oDiv.offsetTop
document.onmousemove = e => {
// 通过事件委托,计算移动的距离
// 因为浏览器里并不能直接取到并且使用clientX、clientY,所以使用事件委托在内部做完赋值
const l = e.clientX - disX
const t = e.clientY - disY
// 计算移动当前元素的位置,并且给该元素样式中的left和top值赋值
oDiv.style.left = l + 'px'
oDiv.style.top = t + 'px'
}
document.onmouseup = e => { // 鼠标抬起,清空之前所在的位置,新拖拽的位置已生成并赋值
document.onmousemove = null
document.onmouseup = null
}
// return false不加的话可能导致黏连,拖到一个地方时div粘在鼠标上不下来,相当于onmouseup失效
return false
}
}
使用的时候跟其他 Vue 指令一样,在绑定的组件中使用 v-drag 即可
<div class="video-pop" v-drag>
因为该方法会导致整个组件都是拖拽区域,因此我在使用的时候做了一些修改,将 onmousedown 的事件,绑定在组件的第一个子元素中,具体情况看实际使用来调整
Vue.directive('drag', function (el) {
const oDiv = el
document.onselectstart = () => {
return false
}
oDiv.onmousedown = e => {
const disX = e.clientX - oDiv.offsetLeft
const disY = e.clientY - oDiv.offsetTop
document.firstChild.onmousemove = e => { // 就是这里,将 onmousedown 的事件,绑定在组件的第一个子元素中
const l = e.clientX - disX
const t = e.clientY - disY
oDiv.style.left = l + 'px'
oDiv.style.top = t + 'px'
}
document.onmouseup = e => {
document.onmousemove = null
document.onmouseup = null
}
return false
}
}