新增drag.js文件
// 拖拽的指令
class Drap {
static zIndex = 1;
constructor(el, option = {}) {
this.el = el;
this.x = 0;
this.y = 0;
this.option = option;
this.init();
this.timeOutEvent = 0;
this.ele = null;
this.lock = true; // 增加锁,处理点击事件和移动事件冲突
}
init() {
this.setEleStyle(this.option || {});
this.el.style.cursor = 'move'; // 鼠标移入整个拖拽块变移动标
//拖拽事件赋值给头部标签,此处代码可实现仅在移动头部时操作整个DOM块
// this.ele = this.el.getElementsByClassName('header')[0]
// if(this.ele){
// this.ele.onmousedown = (e) => {
// this.onMouseDown(e)
// this.el.setCapture && this.el.setCapture() //全局捕获
// }
// }else{
// this.el.onmousedown = (e) => {
// this.onMouseDown(e)
// this.el.setCapture && this.el.setCapture() //全局捕获
// }
// }
this.el.onmousedown = (e) => {
this.gtouchstart(e);
}
// 增加鼠标抬起
this.el.onmouseup = (e) => {
this.gtouchend(e);
}
}
//样式设置
setEleStyle(option) {
for (const key in option) {
this.el.style[key] = option[key]
}
}
//按下ele
onMouseDown(e) {
let zIndex = getComputedStyle(this.el).getPropertyValue('z-index');
zIndex = isNaN(zIndex) ? 1 : zIndex;
Drap.zIndex = Drap.zIndex > zIndex ? Number(Drap.zIndex) + 1 : Number(zIndex) + 1;
this.setEleStyle({
"zIndex": Drap.zIndex,
position: 'fixed',
'cursor': 'move'
});
this.x = e.clientX - this.el.offsetLeft;
this.y = e.clientY - this.el.offsetTop;
document.onmousemove = (e) => this.onMouseMove(e);
document.onmouseup = (e) => this.onMouseUp(e);
}
//移动move,增加锁
onMouseMove(e) {
if (!this.lock) {
this.gtouchmove();
let X = e.clientX - this.x;
let Y = e.clientY - this.y;
// 下面代码操作DOM元素不会移出屏幕,-25应更换为-10,按自己需求设置
if (X < 0) {
X = 0;
} else if (X > document.documentElement.clientWidth - this.el.offsetWidth) {
X = document.documentElement.clientWidth - this.el.offsetWidth - 25;
};
if (Y < 0) {
Y = 0;
} else if (Y > document.documentElement.clientHeight - this.el.offsetHeight) {
Y = document.documentElement.clientHeight - this.el.offsetHeight - 25;
};
this.el.style.left = X + 'px';
this.el.style.top = Y + 'px';
}
}
//释放
onMouseUp(e) {
this.gtouchend();
document.onmousemove = null;
document.onmouseup = null;
this.el.setCapture && this.el.setCapture(); //释放全局捕获
}
gtouchstart(e) {
document.onselectstart = (e) => { return false } // 处理长按选中文字影响
this.timeOutEvent = setTimeout(() => {
this.timeOutEvent = 0;
// 真正长按后应该执行的内容
console.log("长按事件触发发");
this.lock = false;
this.onMouseDown(e);
this.el.setCapture && this.el.setCapture() //全局捕获
}, 200);
return false;
}
gtouchmove() {
clearTimeout(this.timeOutEvent); //清除定时器
this.timeOutEvent = 0;
console.log("取消了");
}
gtouchend() {
clearTimeout(this.timeOutEvent); //清除定时器
this.timeOutEvent = 0;
setTimeout(()=>{
this.lock = true
});
return false;
}
}
const drag = {
mounted(el, binding) {
new Drap(el, binding.value || {})
}
}
export default drag
main.js添加全局导入
import drag from './directives/drag.js'
app.directive('drag', drag)
页面代码使用v-drag
注:mini-dialog为自定义弹框组件
<div class="m-dia" v-if="dialogShow" v-drag>
<mini-dialog @closed="closedMini"></mini-dialog>
</div>
css样式
注意,可移动块必须是top和left属性
.m-dia {
position: absolute;
top: 75%;
left: 70%;
}
结语:
上述代码能完成基础自定义拖拽功能,未测试仅抓取头部才能拖动情况。