Skip to content

Commit 45c6b5f

Browse files
author
Matt Lewis
committed
fix: only call drag start and end outputs when the element is actually dragged
BREAKING CHANGE: drag start and end events are now only called when the element is actually dragged, use regular mousedown and mouseup events to get the old behaviour Fixes #21 Fixes #20
1 parent e4977b9 commit 45c6b5f

File tree

2 files changed

+52
-41
lines changed

2 files changed

+52
-41
lines changed

src/draggable.directive.ts

+14-13
Original file line numberDiff line numberDiff line change
@@ -116,18 +116,8 @@ export class DraggableDirective implements OnInit, OnChanges, OnDestroy {
116116
const pointerDrag: Observable<any> = this.pointerDown
117117
.filter(() => this.canDrag())
118118
.flatMap((pointerDownEvent: PointerEvent) => {
119-
pointerDownEvent.event.preventDefault();
120-
121-
this.zone.run(() => {
122-
this.dragStart.next({ x: 0, y: 0 });
123-
});
124-
125-
this.setCursor(this.dragCursor);
126-
127119
const currentDrag: Subject<any> = new Subject();
128120

129-
this.draggableHelper.currentDrag.next(currentDrag);
130-
131121
const pointerMove: Observable<Coordinates> = this.pointerMove
132122
.map((pointerMoveEvent: PointerEvent) => {
133123
pointerMoveEvent.event.preventDefault();
@@ -169,7 +159,20 @@ export class DraggableDirective implements OnInit, OnChanges, OnDestroy {
169159
.filter(
170160
({ x, y }) => !this.validateDrag || this.validateDrag({ x, y })
171161
)
172-
.takeUntil(Observable.merge(this.pointerUp, this.pointerDown));
162+
.takeUntil(Observable.merge(this.pointerUp, this.pointerDown))
163+
.share();
164+
165+
pointerMove.take(1).subscribe(() => {
166+
pointerDownEvent.event.preventDefault();
167+
168+
this.zone.run(() => {
169+
this.dragStart.next({ x: 0, y: 0 });
170+
});
171+
172+
this.setCursor(this.dragCursor);
173+
174+
this.draggableHelper.currentDrag.next(currentDrag);
175+
});
173176

174177
pointerMove.takeLast(1).subscribe(({ x, y }) => {
175178
this.zone.run(() => {
@@ -186,8 +189,6 @@ export class DraggableDirective implements OnInit, OnChanges, OnDestroy {
186189
}
187190
});
188191

189-
this.pointerMove.next(pointerDownEvent);
190-
191192
return pointerMove;
192193
})
193194
.share();

test/draggable.directive.spec.ts

+38-28
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,11 @@ describe('draggable directive', () => {
5858
const draggableElement: HTMLElement =
5959
fixture.componentInstance.draggable.element.nativeElement;
6060
triggerDomEvent('mousedown', draggableElement, { clientX: 5, clientY: 10 });
61+
triggerDomEvent('mousemove', draggableElement, { clientX: 7, clientY: 10 });
6162
expect(fixture.componentInstance.dragStart).to.have.been.calledWith({
6263
x: 0,
6364
y: 0
6465
});
65-
triggerDomEvent('mousemove', draggableElement, { clientX: 7, clientY: 10 });
6666
expect(fixture.componentInstance.dragging).to.have.been.calledWith({
6767
x: 2,
6868
y: 0
@@ -284,11 +284,11 @@ describe('draggable directive', () => {
284284
const draggableElement: HTMLElement =
285285
fixture.componentInstance.draggable.element.nativeElement;
286286
triggerDomEvent('mousedown', draggableElement, { clientX: 5, clientY: 10 });
287+
triggerDomEvent('mousemove', draggableElement, { clientX: 7, clientY: 10 });
287288
expect(fixture.componentInstance.dragStart).to.have.been.calledWith({
288289
x: 0,
289290
y: 0
290291
});
291-
triggerDomEvent('mousemove', draggableElement, { clientX: 7, clientY: 10 });
292292
expect(fixture.componentInstance.dragging).to.have.been.calledWith({
293293
x: 2,
294294
y: 0
@@ -354,21 +354,23 @@ describe('draggable directive', () => {
354354
const draggableElement: HTMLElement =
355355
fixture.componentInstance.draggable.element.nativeElement;
356356
triggerDomEvent('mousedown', draggableElement, { clientX: 5, clientY: 10 });
357-
expect(fixture.componentInstance.dragStart).to.have.been.calledWith({
358-
x: 0,
359-
y: 0
360-
});
361357
triggerDomEvent('mousemove', draggableElement, { clientX: 3, clientY: 10 });
358+
expect(fixture.componentInstance.dragStart).not.to.have.been.called;
362359
expect(fixture.componentInstance.dragging).not.to.have.been.calledWith({
363360
x: -2,
364361
y: 0
365362
});
366363
triggerDomEvent('mousemove', draggableElement, { clientX: 7, clientY: 8 });
364+
expect(fixture.componentInstance.dragStart).not.to.have.been.called;
367365
expect(fixture.componentInstance.dragging).not.to.have.been.calledWith({
368366
x: 2,
369367
y: -2
370368
});
371369
triggerDomEvent('mousemove', draggableElement, { clientX: 7, clientY: 12 });
370+
expect(fixture.componentInstance.dragStart).to.have.been.calledWith({
371+
x: 0,
372+
y: 0
373+
});
372374
expect(fixture.componentInstance.dragging).to.have.been.calledWith({
373375
x: 2,
374376
y: 2
@@ -424,13 +426,13 @@ describe('draggable directive', () => {
424426
triggerDomEvent('touchstart', draggableElement, {
425427
touches: [{ clientX: 5, clientY: 10 }]
426428
});
429+
triggerDomEvent('touchmove', draggableElement, {
430+
targetTouches: [{ clientX: 7, clientY: 10 }]
431+
});
427432
expect(fixture.componentInstance.dragStart).to.have.been.calledWith({
428433
x: 0,
429434
y: 0
430435
});
431-
triggerDomEvent('touchmove', draggableElement, {
432-
targetTouches: [{ clientX: 7, clientY: 10 }]
433-
});
434436
expect(fixture.componentInstance.dragging).to.have.been.calledWith({
435437
x: 2,
436438
y: 0
@@ -460,13 +462,13 @@ describe('draggable directive', () => {
460462
triggerDomEvent('touchstart', draggableElement, {
461463
touches: [{ clientX: 5, clientY: 10 }]
462464
});
465+
triggerDomEvent('touchmove', draggableElement, {
466+
targetTouches: [{ clientX: 7, clientY: 10 }]
467+
});
463468
expect(fixture.componentInstance.dragStart).to.have.been.calledWith({
464469
x: 0,
465470
y: 0
466471
});
467-
triggerDomEvent('touchmove', draggableElement, {
468-
targetTouches: [{ clientX: 7, clientY: 10 }]
469-
});
470472
expect(fixture.componentInstance.dragging).to.have.been.calledWith({
471473
x: 2,
472474
y: 0
@@ -520,22 +522,6 @@ describe('draggable directive', () => {
520522
).to.equal(touchMoveUnsubscribe);
521523
});
522524

523-
it('should fire the dragEnd event when starting a drag but not actually moving it', () => {
524-
const draggableElement: HTMLElement =
525-
fixture.componentInstance.draggable.element.nativeElement;
526-
triggerDomEvent('mousedown', draggableElement, { clientX: 5, clientY: 10 });
527-
expect(fixture.componentInstance.dragStart).to.have.been.calledWith({
528-
x: 0,
529-
y: 0
530-
});
531-
triggerDomEvent('mouseup', draggableElement, { clientX: 5, clientY: 10 });
532-
expect(fixture.componentInstance.dragEnd).to.have.been.calledWith({
533-
x: 0,
534-
y: 0
535-
});
536-
expect(draggableElement.style.transform).not.to.be.ok;
537-
});
538-
539525
it('should disable the mouse move cursor', () => {
540526
fixture.componentInstance.dragCursor = '';
541527
fixture.detectChanges();
@@ -546,4 +532,28 @@ describe('draggable directive', () => {
546532
triggerDomEvent('mouseleave', draggableElement);
547533
expect(draggableElement.style.cursor).not.to.be.ok;
548534
});
535+
536+
it('should not call dragStart and dragEnd events when clicking on the draggable', () => {
537+
const draggableElement: HTMLElement =
538+
fixture.componentInstance.draggable.element.nativeElement;
539+
triggerDomEvent('mousedown', draggableElement, { clientX: 5, clientY: 10 });
540+
expect(fixture.componentInstance.dragStart).not.to.have.been.called;
541+
expect(fixture.componentInstance.dragging).not.to.have.been.called;
542+
triggerDomEvent('mouseup', draggableElement, { clientX: 5, clientY: 10 });
543+
expect(fixture.componentInstance.dragEnd).not.to.have.been.called;
544+
expect(draggableElement.style.transform).not.to.be.ok;
545+
});
546+
547+
it('should call the drag start, dragging and end events in order', () => {
548+
const draggableElement: HTMLElement =
549+
fixture.componentInstance.draggable.element.nativeElement;
550+
triggerDomEvent('mousedown', draggableElement, { clientX: 5, clientY: 10 });
551+
triggerDomEvent('mousemove', draggableElement, { clientX: 7, clientY: 10 });
552+
triggerDomEvent('mouseup', draggableElement, { clientX: 7, clientY: 8 });
553+
sinon.assert.callOrder(
554+
fixture.componentInstance.dragStart,
555+
fixture.componentInstance.dragging,
556+
fixture.componentInstance.dragEnd
557+
);
558+
});
549559
});

0 commit comments

Comments
 (0)