Skip to content

Commit bebd925

Browse files
author
Matt Lewis
committed
perf(draggable): lazily create the mouse move listener
1 parent 1c62985 commit bebd925

File tree

2 files changed

+39
-9
lines changed

2 files changed

+39
-9
lines changed

src/draggable.directive.ts

+25-9
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,14 @@
1-
import {Directive, HostListener, OnInit, ElementRef, Renderer, Output, EventEmitter, Input, OnDestroy} from '@angular/core';
1+
import {
2+
Directive,
3+
HostListener,
4+
OnInit,
5+
ElementRef,
6+
Renderer,
7+
Output,
8+
EventEmitter,
9+
Input,
10+
OnDestroy
11+
} from '@angular/core';
212
import {Subject} from 'rxjs/Subject';
313
import {Observable} from 'rxjs/Observable';
414
import 'rxjs/add/observable/merge';
@@ -57,6 +67,8 @@ export class Draggable implements OnInit, OnDestroy {
5767
*/
5868
mouseUp: Subject<any> = new Subject();
5969

70+
private mouseMoveEventListenerUnsubscribe: Function;
71+
6072
/**
6173
* @hidden
6274
*/
@@ -158,6 +170,9 @@ export class Draggable implements OnInit, OnDestroy {
158170
}
159171

160172
ngOnDestroy(): void {
173+
if (this.mouseMoveEventListenerUnsubscribe) {
174+
this.mouseMoveEventListenerUnsubscribe();
175+
}
161176
this.mouseDown.complete();
162177
this.mouseMove.complete();
163178
this.mouseUp.complete();
@@ -168,22 +183,23 @@ export class Draggable implements OnInit, OnDestroy {
168183
*/
169184
@HostListener('mousedown', ['$event'])
170185
onMouseDown(event: MouseEvent): void {
186+
if (!this.mouseMoveEventListenerUnsubscribe) {
187+
this.mouseMoveEventListenerUnsubscribe = this.renderer.listenGlobal('document', 'mousemove', (event: MouseEvent) => {
188+
this.mouseMove.next(event);
189+
});
190+
}
171191
this.mouseDown.next(event);
172192
}
173193

174-
/**
175-
* @hidden
176-
*/
177-
@HostListener('document:mousemove', ['$event'])
178-
onMouseMove(event: MouseEvent): void {
179-
this.mouseMove.next(event);
180-
}
181-
182194
/**
183195
* @hidden
184196
*/
185197
@HostListener('document:mouseup', ['$event'])
186198
onMouseUp(event: MouseEvent): void {
199+
if (this.mouseMoveEventListenerUnsubscribe) {
200+
this.mouseMoveEventListenerUnsubscribe();
201+
this.mouseMoveEventListenerUnsubscribe = null;
202+
}
187203
this.mouseUp.next(event);
188204
}
189205

test/draggable.directive.spec.ts

+14
Original file line numberDiff line numberDiff line change
@@ -243,4 +243,18 @@ describe('draggable directive', () => {
243243
expect(fixture.componentInstance.dragEnd).to.have.been.calledOnce;
244244
});
245245

246+
it('should only unregister the mouse move listener if it exists', () => {
247+
const draggableElement: HTMLElement = fixture.componentInstance.draggable.element.nativeElement;
248+
triggerDomEvent('mouseup', draggableElement, {clientX: 7, clientY: 8});
249+
expect(fixture.componentInstance.draggable['mouseMoveEventListenerUnsubscribe']).not.to.be.ok;
250+
});
251+
252+
it('should not register multiple mouse move listeners', () => {
253+
const draggableElement: HTMLElement = fixture.componentInstance.draggable.element.nativeElement;
254+
triggerDomEvent('mousedown', draggableElement, {clientX: 7, clientY: 8});
255+
const mouseMoveUnsubscribe: Function = fixture.componentInstance.draggable['mouseMoveEventListenerUnsubscribe'];
256+
triggerDomEvent('mousedown', draggableElement, {clientX: 7, clientY: 8});
257+
expect(fixture.componentInstance.draggable['mouseMoveEventListenerUnsubscribe']).to.equal(mouseMoveUnsubscribe);
258+
});
259+
246260
});

0 commit comments

Comments
 (0)