mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-23 05:58:26 +08:00
perf(virtual-scroll): scroll events
This commit is contained in:
5
packages/core/src/components.d.ts
vendored
5
packages/core/src/components.d.ts
vendored
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
Reference in New Issue
Block a user