最近在项目中有需求可以拖拽的弹窗,网上搜索了一遍都是服务端创建的弹窗可拖拽,而通过template创建的弹窗确比较难实现,我参考了别人的实现,改造了一下,就可以实现template的拖拽。
drag-modal.directive.ts
import { Directive, ElementRef, Input } from '@angular/core';
import { ModalDragService } from "./drag-modal.service";
import { NzModalRef } from 'ng-zorro-antd/modal';
@Directive({
selector: '[dragModal]'
})
export class DragModalDirective {
@Input() dragModal: NzModalRef;
constructor(private ModalDragService: ModalDragService) {
setTimeout(() => {
this.ModalDragService.dragServiceModal(this.dragModal);
}, 16);
}
}
drag-modal.service.ts
import { Injectable, RendererFactory2 } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class ModalDragService {
constructor( private rendererFactory2: RendererFactory2, ) { }
dragTemplateModal(refModal) {
const render = this.rendererFactory2.createRenderer(null, null);
const modalBackground = refModal.getElement();
const modalElement = refModal.getElement().querySelector('.ant-modal-content');
const modalTitleElement = this.createModalTitleElement(render, modalElement);
this.dragListen(render, modalTitleElement, modalElement, modalBackground);
}
dragServiceModal(refModal) {
refModal.afterOpen.subscribe(() => {
const render = this.rendererFactory2.createRenderer(null, null);
const modalBackground = refModal.getElement();
const modalElement = refModal.getElement().querySelector('.ant-modal-content');
const modalTitleElement = this.createModalTitleElement(render, modalElement);
this.dragListen(render, modalTitleElement, modalElement, modalBackground);
})
}
createModalTitleElement(render, modalElement) {
let element = document.createElement('div') as any;
render.setStyle(element, 'width', '100%');
render.setStyle(element, 'height', '54px');
render.setStyle(element, 'position', 'absolute');
render.setStyle(element, 'top', '0');
render.setStyle(element, 'left', '0');
render.setStyle(element, 'cursor', 'move');
render.setStyle(element, '-moz-user-select', 'none');
render.setStyle(element, '-webkit-user-select', 'none');
render.setStyle(element, '-ms-user-select', 'none');
render.setStyle(element, '-khtml-user-select', 'none');
render.setStyle(element, 'user-select', 'none');
render.appendChild(modalElement, element);
return element;
}
dragListen(render, modalTitleElement, modalElement, modalBackground) {
render.listen(modalTitleElement, 'mousedown', function (event) {
this.mouseDownX = event.clientX;
this.mouseDownY = event.clientY;
this.modalX = modalElement.offsetLeft;
this.modalY = modalElement.offsetTop;
render.setStyle(modalElement, 'left', `${this.modalX}px`);
render.setStyle(modalElement, 'top', `${this.modalY}px`);
this.canMove = true;
}.bind(this));
render.listen(modalTitleElement, 'mouseup', function (event) {
this.canMove = false;
}.bind(this));
render.listen(modalBackground, 'mousemove', function (event) {
if (this.canMove) {
let moveX = event.clientX - this.mouseDownX;
let moveY = event.clientY - this.mouseDownY;
let newModalX = this.modalX + moveX;
let newModalY = this.modalY + moveY;
render.setStyle(modalElement, 'left', `${newModalX}px`);
render.setStyle(modalElement, 'top', `${newModalY}px`);
}
}.bind(this));
}
}
drag-modal.module.ts
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { DragModalDirective } from "./drag-modal.directive";
import { ModalDragService } from "./drag-modal.service";
@NgModule({
providers: [ModalDragService],
declarations: [DragModalDirective],
imports: [
CommonModule,
],
exports: [DragModalDirective]
})
export class ModalDragModule { }
然后把这个模块注入到根模块中,就可以愉快地拖拽了_
#dragModal [dragModal]="dragModal"
<nz-modal
#dragModal
[dragModal]="dragModal">
</nz-modal>