From b2d9e1d8a3922a0cb8e032e8d8bbd55d4c7d3cdb Mon Sep 17 00:00:00 2001 From: Adam Bradley Date: Wed, 18 Nov 2015 23:32:25 -0600 Subject: [PATCH] perf(itemSliding): improve performance --- ionic/components/item/item-sliding-gesture.ts | 51 +++++++++++-------- ionic/components/item/item-sliding.scss | 6 +-- ionic/components/item/test/sliding/main.html | 4 +- ionic/components/list/list.ts | 25 +++++---- ionic/gestures/gesture.ts | 6 ++- 5 files changed, 55 insertions(+), 37 deletions(-) diff --git a/ionic/components/item/item-sliding-gesture.ts b/ionic/components/item/item-sliding-gesture.ts index 83b16407c8..97d6add026 100644 --- a/ionic/components/item/item-sliding-gesture.ts +++ b/ionic/components/item/item-sliding-gesture.ts @@ -20,14 +20,14 @@ export class ItemSlidingGesture extends DragGesture { this.canDrag = true; this.listen(); - this.on('tap', ev => { + this.tap = (ev) => { if (!isFromOptionButtons(ev.target)) { let didClose = this.closeOpened(); if (didClose) { preventDefault(ev); } } - }); + }; this.mouseOut = (ev) => { this.onDragEnd(ev); @@ -38,14 +38,14 @@ export class ItemSlidingGesture extends DragGesture { let itemContainerEle = getItemConatiner(ev.target); if (!itemContainerEle) return; - this.closeOpened(ev, itemContainerEle); + this.closeOpened(itemContainerEle); let openAmout = this.getOpenAmount(itemContainerEle); let itemData = this.get(itemContainerEle); this.preventDrag = (openAmout > 0); if (this.preventDrag) { - this.closeOpened(ev); + this.closeOpened(); return preventDefault(ev); } @@ -57,16 +57,18 @@ export class ItemSlidingGesture extends DragGesture { if (ev.srcEvent.type.indexOf('mouse') > -1) { ev.target.addEventListener('mouseout', this.mouseOut); } + + this.dragEnded = false; } onDrag(ev) { - if (Math.abs(ev.deltaY) > 30) { + if (this.dragEnded || this.preventDrag || Math.abs(ev.deltaY) > 30) { this.preventDrag = true; - return this.closeOpened(ev); + return; } let itemContainerEle = getItemConatiner(ev.target); - if (!itemContainerEle || !isActive(itemContainerEle) || this.preventDrag) return; + if (!itemContainerEle || !isActive(itemContainerEle)) return; let itemData = this.get(itemContainerEle); @@ -75,9 +77,6 @@ export class ItemSlidingGesture extends DragGesture { if (!itemData.optsWidth) return; } - itemContainerEle.classList.add('active-slide'); - itemContainerEle.classList.add('active-options'); - let x = ev.center[this.direction]; let delta = x - itemData.startX; @@ -88,11 +87,18 @@ export class ItemSlidingGesture extends DragGesture { newX = -Math.min(-itemData.optsWidth, -itemData.optsWidth + (((delta + itemData.optsWidth) * 0.4))); } - this.open(itemContainerEle, newX, false); + raf(() => { + if (!this.dragEnded && !this.preventDrag) { + isItemActive(itemContainerEle, true); + this.open(itemContainerEle, newX, false); + } + }); } onDragEnd(ev) { this.preventDrag = false; + this.dragEnded = true; + let itemContainerEle = getItemConatiner(ev.target); if (!itemContainerEle || !isActive(itemContainerEle)) return; @@ -108,12 +114,7 @@ export class ItemSlidingGesture extends DragGesture { if (this.getOpenAmount(itemContainerEle) < (restingPoint / 2)) { // If we are going left but too slow, or going right, go back to resting - if (ev.direction & Hammer.DIRECTION_RIGHT) { - // Left - restingPoint = 0; - - } else if (Math.abs(ev.velocityX) < 0.3) { - // Right + if (ev.direction & Hammer.DIRECTION_RIGHT || Math.abs(ev.velocityX) < 0.3) { restingPoint = 0; } } @@ -125,7 +126,7 @@ export class ItemSlidingGesture extends DragGesture { }); } - closeOpened(ev, doNotCloseEle) { + closeOpened(doNotCloseEle) { let didClose = false; if (this.openItems) { let openItemElements = this.listEle.querySelectorAll('.active-slide'); @@ -153,8 +154,7 @@ export class ItemSlidingGesture extends DragGesture { } else { let timerId = setTimeout(() => { if (slidingEle.style[CSS.transform] === '') { - itemContainerEle.classList.remove('active-slide'); - itemContainerEle.classList.remove('active-options'); + isItemActive(itemContainerEle, false); this.openItems--; } }, 400); @@ -165,6 +165,12 @@ export class ItemSlidingGesture extends DragGesture { slidingEle.style[CSS.transform] = (openAmount ? 'translate3d(' + -openAmount + 'px,0,0)' : ''); if (isFinal) { + if (openAmount) { + isItemActive(itemContainerEle, true); + this.on('tap', this.tap); + } else { + this.off('tap', this.tap); + } this.enableScroll(!openAmount); } } @@ -197,6 +203,11 @@ export class ItemSlidingGesture extends DragGesture { } } +function isItemActive(ele, isActive) { + ele.classList[isActive ? 'add' : 'remove']('active-slide'); + ele.classList[isActive ? 'add' : 'remove']('active-options'); +} + function preventDefault(ev) { ev.preventDefault(); } diff --git a/ionic/components/item/item-sliding.scss b/ionic/components/item/item-sliding.scss index a6539f06d1..299b14fdd3 100644 --- a/ionic/components/item/item-sliding.scss +++ b/ionic/components/item/item-sliding.scss @@ -21,7 +21,7 @@ ion-item-options { right: 0; z-index: $z-index-item-options; height: 100%; - opacity: 0; + visibility: hidden; } ion-item-sliding.active-slide { @@ -39,7 +39,7 @@ ion-item-sliding.active-slide { display: flex; } - &.active-options ion-item-options{ - opacity: 1; + &.active-options ion-item-options { + visibility: visible; } } diff --git a/ionic/components/item/test/sliding/main.html b/ionic/components/item/test/sliding/main.html index 0b2884cbbe..6e4b3a2b42 100644 --- a/ionic/components/item/test/sliding/main.html +++ b/ionic/components/item/test/sliding/main.html @@ -83,9 +83,9 @@ - + -

ng-for {{item}}

+

ng-for {{data}}

diff --git a/ionic/components/list/list.ts b/ionic/components/list/list.ts index 1c3bfd9372..8066682cd7 100644 --- a/ionic/components/list/list.ts +++ b/ionic/components/list/list.ts @@ -33,6 +33,7 @@ export class List extends Ion { constructor(elementRef: ElementRef, config: Config, private zone: NgZone) { super(elementRef, config); this.ele = elementRef.nativeElement; + this._enableSliding = false; } /** @@ -76,18 +77,22 @@ export class List extends Ion { } enableSlidingItems(shouldEnable) { - this._enableSliding = shouldEnable; - if (this._init) { - if (shouldEnable) { - this.zone.runOutsideAngular(() => { - setTimeout(() => { - this.slidingGesture = new ItemSlidingGesture(this, this.ele); - }); - }); - } else { - this.slidingGesture && this.slidingGesture.unlisten(); + if (this._enableSliding !== shouldEnable) { + this._enableSliding = shouldEnable; + + if (shouldEnable) { + console.debug('enableSlidingItems'); + this.zone.runOutsideAngular(() => { + setTimeout(() => { + this.slidingGesture = new ItemSlidingGesture(this, this.ele); + }); + }); + + } else { + this.slidingGesture && this.slidingGesture.unlisten(); + } } } } diff --git a/ionic/gestures/gesture.ts b/ionic/gestures/gesture.ts index 271014c85c..dee0186f8f 100644 --- a/ionic/gestures/gesture.ts +++ b/ionic/gestures/gesture.ts @@ -35,7 +35,10 @@ export class Gesture { } this.hammertime.on(type, cb); (this._callbacks[type] || (this._callbacks[type] = [])).push(cb); - //this.element.addEventListener(type, cb); + } + + off(type, cb) { + this.hammertime.off(type, this._callbacks[type] ? cb : null); } listen() { @@ -46,7 +49,6 @@ export class Gesture { if (this.hammertime) { for (let type in this._callbacks) { for (let i = 0; i < this._callbacks[type].length; i++) { - //this.element.removeEventListener(type, this._callbacks[type][i]); this.hammertime.off(type, this._callbacks[type]); } }