Angular自定义拖动指令
使用方法:
在需要实现可拖动的元素上加入 appDrag 属性即可;
若需要在宿主元素的上层元素中找到指定的class中包含类名ant-modal的元素,使之可拖动,只须加入
[appDrag]="'ant-modal'" 属性即可
import { Directive, ElementRef, HostListener, Input, OnInit } from '@angular/core';
@Directive({
selector: '[appDrag]',
})
export class DragDirective implements OnInit {
private isDown = false;
private disX = 0;
private disY = 0;
private dom: any;
@Input('appDrag') className: string;
constructor(private el: ElementRef) {
}
@HostListener('drag', ['event'])
dragEvent() {
console.log('drag');
}
ngOnInit() {
}
/**
*点击事件
*/
@HostListener('mousedown', ['$event']) onMousedown(event) {
if (!this.isDown) {
this.dom = this.getParentRecurse(this.el.nativeElement, this.className);
// 移动区域
this.isDown = true;
this.disX = event.clientX - this.dom.offsetLeft;
this.disY = event.clientY - this.dom.offsetTop;
}
}
/**
* 递归查找获取类名包含className的节点
* @param dom
* @param className
*/
getParentRecurse(dom: any, className: string) {
if (!className) {
console.log(`未传递className参数`);
return dom;
}
if (dom.classList.contains(className)) {
return dom;
} else if (dom.parentNode) {
return this.getParentRecurse(dom.parentNode, className);
} else {
console.log(`未找到className为${className}的节点,直接返回`);
return dom;
}
}
/**
* 监听document移动事件事件
*/
@HostListener('document:mousemove', ['$event']) onMousemove(event) {
if (this.isDown) {
const cw = document.documentElement.clientWidth;
const cy = document.documentElement.clientHeight;
const dw = this.dom.offsetWidth;
const dh = this.dom.offsetHeight;
let oLeft = event.clientX - this.disX;
let oTop = event.clientY - this.disY;
if (oTop < 0) {
oTop = 0;
} else if (oTop > cy - dh) {
oTop = cy - dh;
}
if (oLeft < 0) {
oLeft = 0;
} else if (oLeft > cw - dw) {
oLeft = cw - dw;
}
this.dom.style.left = oLeft + 'px';
this.dom.style.top = oTop + 'px';
this.dom.style.position = 'fixed';
this.el.nativeElement.style.cursor = 'move';
}
}
/**
* 监听document离开事件
*/
@HostListener('document:mouseup', ['$event']) onMouseup() {
if (this.isDown) {
document.onmousemove = null;
document.onmouseup = null;
this.isDown = false;
}
}
}