Vue3自定义drag指令

新增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%;
}

结语:
上述代码能完成基础自定义拖拽功能,未测试仅抓取头部才能拖动情况。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值