Skip to content

Commit 28b35f1

Browse files
committed
perf: dont trigger repaint when starting to drag items
1 parent a5a4566 commit 28b35f1

File tree

2 files changed

+25
-47
lines changed

2 files changed

+25
-47
lines changed

projects/angular-draggable-droppable/src/lib/draggable.directive.spec.ts

+14-25
Original file line numberDiff line numberDiff line change
@@ -764,21 +764,6 @@ describe('draggable directive', () => {
764764
.true;
765765
});
766766

767-
it('should make all elements on the page unable to select text while dragging', () => {
768-
const tmp = document.createElement('div');
769-
tmp.innerHTML = 'foo';
770-
document.body.appendChild(tmp);
771-
expect(getComputedStyle(tmp).userSelect).to.equal('auto');
772-
const draggableElement =
773-
fixture.componentInstance.draggableElement.nativeElement;
774-
triggerDomEvent('mousedown', draggableElement, { clientX: 5, clientY: 10 });
775-
expect(getComputedStyle(tmp).userSelect).to.equal('none');
776-
triggerDomEvent('mousemove', draggableElement, { clientX: 7, clientY: 10 });
777-
expect(getComputedStyle(tmp).userSelect).to.equal('none');
778-
triggerDomEvent('mouseup', draggableElement, { clientX: 7, clientY: 8 });
779-
expect(getComputedStyle(tmp).userSelect).to.equal('auto');
780-
});
781-
782767
it('should cancel the drag', () => {
783768
const draggableElement =
784769
fixture.componentInstance.draggableElement.nativeElement;
@@ -817,19 +802,13 @@ describe('draggable directive', () => {
817802
fixture.componentInstance.draggableElement.nativeElement;
818803
triggerDomEvent('mousedown', draggableElement, { clientX: 5, clientY: 10 });
819804
triggerDomEvent('mousemove', draggableElement, { clientX: 7, clientY: 10 });
820-
expect(getComputedStyle(document.body.children[0]).userSelect).to.equal(
821-
'none'
822-
);
823805
triggerDomEvent('mousemove', draggableElement, { clientX: 7, clientY: 8 });
824806
fixture.destroy();
825807
expect(fixture.componentInstance.dragEnd).to.have.been.calledWith({
826808
x: 2,
827809
y: -2,
828810
dragCancelled: false
829811
});
830-
expect(getComputedStyle(document.body.children[0]).userSelect).to.equal(
831-
'auto'
832-
);
833812
});
834813

835814
it('should use the contents of the ghost element template as the inner html of the ghost element', () => {
@@ -884,17 +863,27 @@ describe('draggable directive', () => {
884863
});
885864
});
886865

887-
it('should allow elements to be selected if clicking but not dragging the element', () => {
866+
it('should prevent text from being selected while dragging', () => {
888867
const tmp = document.createElement('div');
889868
tmp.innerHTML = 'foo';
890869
document.body.appendChild(tmp);
891-
expect(getComputedStyle(tmp).userSelect).to.equal('auto');
870+
const preventDefault = sinon.spy();
871+
triggerDomEvent('selectstart', tmp, {
872+
preventDefault
873+
});
874+
expect(preventDefault).not.to.have.been.called;
892875
const draggableElement =
893876
fixture.componentInstance.draggableElement.nativeElement;
894877
triggerDomEvent('mousedown', draggableElement, { clientX: 5, clientY: 10 });
895-
expect(getComputedStyle(tmp).userSelect).to.equal('none');
878+
triggerDomEvent('selectstart', tmp, {
879+
preventDefault
880+
});
881+
expect(preventDefault).to.have.been.calledOnce;
896882
triggerDomEvent('mouseup', draggableElement, { clientX: 5, clientY: 10 });
897-
expect(getComputedStyle(tmp).userSelect).to.equal('auto');
883+
triggerDomEvent('selectstart', tmp, {
884+
preventDefault
885+
});
886+
expect(preventDefault).to.have.been.calledOnce;
898887
});
899888

900889
it('should allow for draggable elements to be inside other draggable elements', () => {

projects/angular-draggable-droppable/src/lib/draggable.directive.ts

+11-22
Original file line numberDiff line numberDiff line change
@@ -250,24 +250,6 @@ export class DraggableDirective implements OnInit, OnChanges, OnDestroy {
250250
pointerDownEvent.event.stopPropagation();
251251
}
252252

253-
// hack to prevent text getting selected in safari while dragging
254-
const globalDragStyle: HTMLStyleElement = this.renderer.createElement(
255-
'style'
256-
);
257-
this.renderer.setAttribute(globalDragStyle, 'type', 'text/css');
258-
this.renderer.appendChild(
259-
globalDragStyle,
260-
this.renderer.createText(`
261-
body * {
262-
-moz-user-select: none;
263-
-ms-user-select: none;
264-
-webkit-user-select: none;
265-
user-select: none;
266-
}
267-
`)
268-
);
269-
this.document.head.appendChild(globalDragStyle);
270-
271253
const startScrollPosition = this.getScrollPosition();
272254

273255
const scrollContainerScroll$ = new Observable(observer => {
@@ -494,10 +476,17 @@ export class DraggableDirective implements OnInit, OnChanges, OnDestroy {
494476
currentDrag$.complete();
495477
});
496478

497-
merge(dragComplete$, dragEnded$)
498-
.pipe(take(1))
499-
.subscribe(() => {
500-
this.document.head.removeChild(globalDragStyle);
479+
const selectionStart$ = new Observable<Event>(observer => {
480+
return this.renderer.listen('document', 'selectstart', e =>
481+
observer.next(e)
482+
);
483+
});
484+
485+
// hack to prevent text getting selected in safari while dragging
486+
selectionStart$
487+
.pipe(takeUntil(merge(dragComplete$, dragEnded$)))
488+
.subscribe(event => {
489+
event.preventDefault();
501490
});
502491

503492
return pointerMove;

0 commit comments

Comments
 (0)