perf(virtual-scroll): scroll events

This commit is contained in:
Manu Mtz.-Almeida
2018-02-09 18:14:06 +01:00
parent 9226684826
commit 3d5abffdd6
7 changed files with 36 additions and 74 deletions

View File

@ -759,9 +759,6 @@ declare global {
namespace JSXElements {
export interface IonContentAttributes extends HTMLAttributes {
fullscreen?: boolean;
ionScroll?: Function;
ionScrollEnd?: Function;
ionScrollStart?: Function;
}
}
}
@ -2530,10 +2527,10 @@ declare global {
}
namespace JSXElements {
export interface IonScrollAttributes extends HTMLAttributes {
disabled?: boolean;
onionScroll?: ScrollCallback;
onionScrollEnd?: ScrollCallback;
onionScrollStart?: ScrollCallback;
scrollEvents?: boolean;
}
}
}

View File

@ -25,21 +25,6 @@ export class Content {
@Prop({ context: 'config' }) config: Config;
@Prop({ context: 'dom' }) dom: DomController;
/**
* Emitted when the scrolling first starts.
*/
@Prop() ionScrollStart: Function;
/**
* Emitted on every scroll event.
*/
@Prop() ionScroll: Function;
/**
* Emitted when scrolling ends.
*/
@Prop() ionScrollEnd: Function;
/**
* If true, the content will scroll behind the headers
* and footers. This effect can easily be seen by setting the toolbar

View File

@ -25,27 +25,6 @@ and footers. This effect can easily be seen by setting the toolbar
to transparent.
#### ionScroll
Emitted on every scroll event.
#### ionScrollEnd
Emitted when scrolling ends.
#### ionScrollStart
Emitted when the scrolling first starts.
## Attributes
#### fullscreen
@ -57,27 +36,6 @@ and footers. This effect can easily be seen by setting the toolbar
to transparent.
#### ion-scroll
Emitted on every scroll event.
#### ion-scroll-end
Emitted when scrolling ends.
#### ion-scroll-start
Emitted when the scrolling first starts.
## Methods
#### scrollToBottom()

View File

@ -227,6 +227,9 @@ export class InfiniteScroll {
private enableScrollEvents(shouldListen: boolean) {
if (this.scrollEl) {
if (shouldListen) {
this.scrollEl.scrollEvents = true;
}
this.enableListener(this, 'ionScroll', shouldListen, this.scrollEl);
}
}

View File

@ -1,4 +1,4 @@
import { Component, Element, Event, EventEmitter, Listen, Method, Prop } from '@stencil/core';
import { Component, Element, Event, EventEmitter, EventListenerEnable, Listen, Method, Prop, Watch } from '@stencil/core';
import { Config, DomController, GestureDetail } from '../../index';
import { GestureController, GestureDelegate } from '../gesture-controller/gesture-controller';
@ -21,11 +21,10 @@ export class Scroll {
@Element() private el: HTMLElement;
@Prop({ context: 'config'}) config: Config;
@Prop({ context: 'enableListener'}) enableListener: EventListenerEnable;
@Prop({ context: 'dom' }) dom: DomController;
@Prop({ context: 'isServer' }) isServer: boolean;
@Prop() disabled = false;
@Prop() onionScrollStart: ScrollCallback;
@Prop() onionScroll: ScrollCallback;
@Prop() onionScrollEnd: ScrollCallback;
@ -45,6 +44,13 @@ export class Scroll {
*/
@Event() ionScrollEnd: EventEmitter;
@Prop() scrollEvents = false;
@Watch('scrollEvents')
scrollChanged(enabled: boolean) {
this.enableListener(this, 'scroll', enabled);
}
componentDidLoad() {
if (this.isServer) {
return;
@ -53,6 +59,7 @@ export class Scroll {
const gestureCtrl = Ionic.gesture = Ionic.gesture || new GestureController();
this.gesture = gestureCtrl.createGesture('scroll', 100, false);
this.app = this.el.closest('ion-app') as HTMLIonAppElement;
this.scrollChanged(this.scrollEvents);
}
componentDidUnload() {
@ -62,7 +69,7 @@ export class Scroll {
// Native Scroll *************************
@Listen('scroll', { passive: true })
@Listen('scroll', { passive: true, enabled: false })
onNativeScroll() {
if (!this.queued) {
this.queued = true;

View File

@ -21,10 +21,10 @@ export const enum NodeChange {
}
export interface Cell {
type: CellType;
value: any;
i: number;
index: number;
value: any;
type: CellType;
height: number;
reads: number;
visible: boolean;
@ -35,6 +35,7 @@ export interface VirtualNode {
top: number;
change: NodeChange;
d: boolean;
visible: boolean;
}
const MIN_READS = 2;
@ -88,6 +89,7 @@ export function updateVDom(dom: VirtualNode[], heightIndex: Uint32Array, cells:
dom.push({
d: false,
cell: cell,
visible: true,
change: NodeChange.Cell,
top: heightIndex[index],
});
@ -106,8 +108,10 @@ export function doRender(
el: HTMLElement,
itemRender: ItemRenderFn,
dom: VirtualNode[],
updateCellHeight: Function) {
updateCellHeight: Function
) {
const children = el.children;
const childrenNu = children.length;
let child: HTMLElement;
for (let i = 0; i < dom.length; i++) {
const node = dom[i];
@ -115,7 +119,7 @@ export function doRender(
// the cell change, the content must be updated
if (node.change === NodeChange.Cell) {
if (i < children.length) {
if (i < childrenNu) {
child = children[i] as HTMLElement;
itemRender(child, cell, i);
} else {
@ -132,13 +136,22 @@ export function doRender(
if (node.change !== NodeChange.NoChange) {
child.style.transform = `translate3d(0,${node.top}px,0)`;
}
if (cell.visible) {
// update visibility
const visible = cell.visible;
if (node.visible !== visible) {
if (visible) {
child.classList.remove('virtual-loading');
} else {
child.classList.add('virtual-loading');
}
node.visible = visible;
}
// dynamic height inference
if (cell.reads > 0) {
updateCellHeight(cell, child);
cell.reads--;
}
}
}

View File

@ -228,7 +228,6 @@ export class VirtualScroll {
return;
}
cell.visible = true;
cell.reads--;
if (cell.height !== height) {
console.debug(`[${cell.reads}] cell size ${cell.height} -> ${height}`);
cell.height = height;