Vue自定义指令实现元素拖拽(ts版本)
Vue自定义实现元素拖拽,代码如下
import Vue, { DirectiveOptions } from 'vue';
const elDrag: DirectiveOptions = {
bind(el, binding) {
const dragEl = [].find.call(el.childNodes, (node: any) => node.id === 'drag-el') || el;
(dragEl as any).onmousedown = (e: any) => {
e = e || window.event; // 事件源对象兼容
el.style.cursor = 'move';
const { offsetTop, offsetLeft, offsetWidth, offsetHeight } = el; // 获取拖拽元素的位置和大小
let maxX = 0;
let maxY = 0;
// 是否允许拖拽元素超出页面
if (!binding.value.overRange) {
maxX = window.innerWidth - offsetWidth;
maxY = window.innerHeight - offsetHeight;
}
// 拖拽时阻止浏览器默认事件
if ((dragEl as any).setCapture) {
(dragEl as any).setCapture();
} else {
e.preventDefault ? e.preventDefault() : e.returnValue = false;
}
// 获取鼠标位置和拖拽元素位置的偏差
const deltaX = e.clientX - offsetLeft;
const deltaY = e.clientY - offsetTop;
document.onmousemove = (event: any) => {
event = event || window.event; // 事件源对象兼容
const { clientX, clientY } = event;
let left = clientX - deltaX;
let top = clientY - deltaY;
// 是否允许拖拽元素超出页面
if (!binding.value.overRange) {
left = left > 0 ? left > maxX ? maxX : left : 0;
top = top > 0 ? top > maxY ? maxY : top : 0;
}
// 鼠标
if (clientX > 0 && clientX < window.innerWidth) {
el.style.left = `${left}px`;
}
if (clientY > 0 && clientY < window.innerHeight) {
el.style.top = `${top}px`;
}
};
};
document.onmouseup = () => {
el.style.cursor = '';
document.onmousemove = null;
document.onmouseup = null;
};
}
};
Vue.directive('el-drag', elDrag);
使用方式:在需要拖拽的元素绑定v-el-drag指令。 overRange设置是否允许元素离开页面可视区;如需设置元素某子元素为拖拽目标,给目标子元素添加id="drag-el"即可
<div v-el-drag="{ overRange: false }">
<div id="drag-el">拖拽目标</div>
</div>
目前只是基础实现拖拽,更多配置功能还在思考中……