附加条件:不能超出父元素
实现思路: 使用vue自定义指令directives, 监听鼠标按下事件,计算按下时目标元素与父元素的距离,最后通过CSS position-absolute : left / top实现距离改变
(父元素需要有宽高,且有position定位)
1、vue文件中实现
使用directives
template中使用指令
script中定义指令
ini
methods: {},
directives: {
drag: {
inserted: function(el) {
// console.log('el:', el)
let oDiv = el; // 当前元素
// 禁止选择拖拽块上的文字
document.onselectstart = function () {
return false;
};
oDiv.onmousedown = function (e) {
// 获取父元素dom
let pbox = document.getElementById('video-wrap-hls')
// console.log('parent-box', pbox.clientWidth, pbox.clientHeight)
// console.log('child-box', oDiv.clientWidth, oDiv.clientHeight)
// console.log('e:', e, oDiv.offsetLeft, oDiv.offsetTop)
// 鼠标按下,计算当前元素距离可视区的距离
let disX = e.clientX - oDiv.offsetLeft;
let disY = e.clientY - oDiv.offsetTop;
document.onmousemove = function (e) {
// 通过事件委托,计算移动的距离
let l = e.clientX - disX;
let t = e.clientY - disY;
if (l < 0) {
l = 0
} else if (l > (pbox.clientWidth - oDiv.clientWidth)) {
l = pbox.clientWidth - oDiv.clientWidth
}
if (t < 0) {
t = 0
} else if (t > (pbox.clientHeight - oDiv.clientHeight)) {
t = pbox.clientHeight - oDiv.clientHeight
}
// 移动当前元素
oDiv.style.left = l + "px";
oDiv.style.top = t + "px";
};
document.onmouseup = function (e) {
document.onmousemove = null;
document.onmouseup = null;
};
// 防止黏连
return false;
};
},
}
},
2、main.js全局引入
创建directives.js 在入口文件引入 并Vue.use,实现代码与文件内实现基本相同。
vue官方directive使用方法
from vue官网
from vue官网
项目中使用
在入口文件引入并使用
上述步骤完成后可直接在页面文件中使用
3、小坑
需注意如果css使用了transition过渡, 不能使用all 因为 left / top 改变也会发生过渡 导致发生拖拽延迟效果
如果需要鼠标hover后有动画效果 可以分别写出来
栗子