一. HTML和 CSS
html結構大概如下:
<div class="background"> <div appDrag class="modal"> // 在模態框所在的 div 添加屬性 [appDrag] <div class="header drag-title"> <div class="icon-close"></div> </div> <div class="dialog-center"> </div> </div> </div>
.background { // background為模態框后面的覆蓋層,大小均設置為100%; position: fixed; width: 100%; height: 100%; top: 0; left: 0; z-index: 3000; background: transparent; -webkit-transition: all 0.3s; transition: all 0.3s; } .modal { // 相對於 background 定位, 位置暫時設置為 0,0,0,0 在指令中將其位置水平垂直居中在頁面中間 position: absolute; top: 0; left: 0; bottom: 0; right: 0; width: 514px; height: 290px; z-index: 3100; background: #ffffff; box-shadow: 1px 1px 20px rgba(0,0,0,.3); border-radius: 3px; }
二:創建drag.directive.ts
使用 angular cli 命令自動生成指令drag,該命令會自動在app.module.ts中導入drag指令。
ng g directive directives/drag
或者手動在根模塊引入指令:
// 導入指令--->用法類似於組件 import { DragDirective } from './directives/drag.directive'; // 列出程序中的組件 declarations: [ · · · DragDirective ],
三:下面是拖拽指令主要邏輯;
import { Directive, ElementRef, HostListener, OnInit } from '@angular/core'; import { fromEvent } from 'rxjs'; @Directive({ selector: '[appDrag]' }) export class DragDirective implements OnInit { private isDown = false; private disX = 0; private disY = 0; constructor(private el: ElementRef) { } /* ElementRef是一個服務,它賦予我們通過它的nativeElement屬性直接訪問 "DOM 元素"的能力 */ ngOnInit() { this.el.nativeElement.style.left = (document.documentElement.clientWidth - this.el.nativeElement.offsetWidth) / 2 + 'px'; this.el.nativeElement.style.top = (document.documentElement.clientHeight - this.el.nativeElement.offsetHeight) / 2 + 'px'; /* 模態框距左邊的距離是document的寬度減去模態框的寬度除以二,同理得出距上面的距離 */ fromEvent(window, 'resize').subscribe(() => { this.el.nativeElement.style.left = (document.documentElement.clientWidth - this.el.nativeElement.offsetWidth) / 2 + 'px'; this.el.nativeElement.style.top = (document.documentElement.clientHeight - this.el.nativeElement.offsetHeight) / 2 + 'px'; }); /* 監控瀏覽區大小變化,將其設置在瀏覽器中間位置 */ } // 點擊事件 @HostListener('mousedown', ['$event']) onMousedown(event) { // 禁止選中close if (event.target.className.indexOf('icon-close') !== -1) { return; } console.log(event); if (event.target.className.indexOf('drag-title') !== -1) { // 移動區域 this.isDown = true; this.disX = event.clientX - this.el.nativeElement.offsetLeft; this.disY = event.clientY - this.el.nativeElement.offsetTop; } } // 監聽document移動事件事件 @HostListener('document:mousemove', ['$event']) onMousemove(event) { // 判斷該元素是否被點擊了。 if (this.isDown) { // 移動中; const newdisX = event.clientX; const newdisY = event.clientY; let oLeft = newdisX - this.disX; let oTop = newdisY - this.disY; if (oLeft < 0) { oLeft = 0; } else if (oLeft > document.documentElement.clientWidth - this.el.nativeElement.offsetWidth) { oLeft = document.documentElement.clientWidth - this.el.nativeElement.offsetWidth; } if (oTop < 0) { oTop = 0; } else if (oTop > document.documentElement.clientHeight - this.el.nativeElement.offsetHeight) { oTop = document.documentElement.clientHeight - this.el.nativeElement.offsetHeight; } this.el.nativeElement.style.left = oLeft + 'px'; this.el.nativeElement.style.top = oTop + 'px'; } } // 監聽document離開事件 @HostListener('document:mouseup', ['$event']) onMouseup() { // 只用當元素移動過了,離開函數體才會觸發。 if (this.isDown) { document.onmousemove = null; document.onmouseup = null; this.isDown = false; } } }