perf(itemSliding): improve performance

This commit is contained in:
Adam Bradley
2015-11-18 23:32:25 -06:00
parent 564b674ba7
commit b2d9e1d8a3
5 changed files with 55 additions and 37 deletions

View File

@@ -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();
}

View File

@@ -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;
}
}

View File

@@ -83,9 +83,9 @@
</ion-item-options>
</ion-item-sliding>
<ion-item-sliding *ng-for="#item of getItems()">
<ion-item-sliding *ng-for="#data of getItems()" #item>
<ion-item text-wrap detail-push>
<h3>ng-for {{item}}</h3>
<h3>ng-for {{data}}</h3>
</ion-item>
<ion-item-options>
<button primary (click)="archive($event, item)">Archive</button>

View File

@@ -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();
}
}
}
}

View File

@@ -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]);
}
}