Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(content): scroll listener is auto enabled #10962

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 27 additions & 11 deletions src/components/content/content.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ChangeDetectionStrategy, Component, ElementRef, EventEmitter, Input, NgZone, OnDestroy, Optional, Output, Renderer, ViewChild, ViewEncapsulation } from '@angular/core';
import { AfterViewInit, ChangeDetectionStrategy, Component, ElementRef, EventEmitter, Input, NgZone, OnDestroy, Optional, Output, Renderer, ViewChild, ViewEncapsulation } from '@angular/core';

import { App } from '../app/app';
import { Config } from '../../config/config';
Expand All @@ -17,6 +17,14 @@ import { ViewController } from '../../navigation/view-controller';
export { ScrollEvent } from '../../util/scroll-view';


export class EventEmitterProxy<T> extends EventEmitter<T> {
onSubscribe: Function;
subscribe(generatorOrNext?: any, error?: any, complete?: any): any {
this.onSubscribe();
return super.subscribe(generatorOrNext, error, complete);
}
}

/**
* @name Content
* @description
Expand Down Expand Up @@ -125,7 +133,7 @@ export { ScrollEvent } from '../../util/scroll-view';
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None
})
export class Content extends Ion implements OnDestroy {
export class Content extends Ion implements OnDestroy, AfterViewInit {
/** @internal */
_cTop: number;
/** @internal */
Expand Down Expand Up @@ -312,17 +320,17 @@ export class Content extends Ion implements OnDestroy {
/**
* @output {ScrollEvent} Emitted when the scrolling first starts.
*/
@Output() ionScrollStart: EventEmitter<ScrollEvent> = new EventEmitter<ScrollEvent>();
@Output() ionScrollStart: EventEmitterProxy<ScrollEvent> = new EventEmitterProxy<ScrollEvent>();

/**
* @output {ScrollEvent} Emitted on every scroll event.
*/
@Output() ionScroll: EventEmitter<ScrollEvent> = new EventEmitter<ScrollEvent>();
@Output() ionScroll: EventEmitterProxy<ScrollEvent> = new EventEmitterProxy<ScrollEvent>();

/**
* @output {ScrollEvent} Emitted when scrolling ends.
*/
@Output() ionScrollEnd: EventEmitter<ScrollEvent> = new EventEmitter<ScrollEvent>();
@Output() ionScrollEnd: EventEmitterProxy<ScrollEvent> = new EventEmitterProxy<ScrollEvent>();


constructor(
Expand All @@ -339,6 +347,11 @@ export class Content extends Ion implements OnDestroy {
) {
super(config, elementRef, renderer, 'content');

let enableScrollListener = this.enableScrollListener.bind(this);
this.ionScroll.onSubscribe = enableScrollListener;
this.ionScrollStart.onSubscribe = enableScrollListener;
this.ionScrollEnd.onSubscribe = enableScrollListener;

this.statusbarPadding = config.getBoolean('statusbarPadding', false);
this._imgReqBfr = config.getNumber('imgRequestBuffer', 1400);
this._imgRndBfr = config.getNumber('imgRenderBuffer', 400);
Expand All @@ -348,7 +361,8 @@ export class Content extends Ion implements OnDestroy {
// goal is to completely remove this when iOS
// fully supports scroll events
// listen to JS scroll events
this._scroll = new ScrollView(_plt, _dom, config.getBoolean('virtualScrollEventAssist'));
const jsScroll = config.getBoolean('virtualScrollEventAssist');
this._scroll = new ScrollView(_app, _plt, _dom, jsScroll);

while (navCtrl) {
if (isTabs(<any>navCtrl)) {
Expand Down Expand Up @@ -383,7 +397,7 @@ export class Content extends Ion implements OnDestroy {
/**
* @hidden
*/
enableScrollListener() {
ngAfterViewInit() {
assert(this.getFixedElement(), 'fixed element was not found');
assert(this.getScrollElement(), 'scroll element was not found');

Expand All @@ -398,9 +412,6 @@ export class Content extends Ion implements OnDestroy {

// subscribe to every scroll move
scroll.onScroll = (ev) => {
// remind the app that it's currently scrolling
this._app.setScrolling();

// emit to all of our other friends things be scrolling
this.ionScroll.emit(ev);

Expand All @@ -413,8 +424,13 @@ export class Content extends Ion implements OnDestroy {

this.imgsUpdate();
};
}

scroll.setEnabled();
/**
* @hidden
*/
enableScrollListener() {
this._scroll.eventsEnabled = true;
}

/**
Expand Down
4 changes: 2 additions & 2 deletions src/util/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,8 @@ export function setupEvents(plt: Platform, dom: DomController): Events {
let contentEle = <any>el.closest('.scroll-content');
if (contentEle) {
var style = contentEle.style;
var scroll = new ScrollView(plt, dom, false);
scroll.init(contentEle, 0, 0);
var scroll = new ScrollView(null, plt, dom, false);
scroll._el = contentEle;
// We need to stop scrolling if it's happening and scroll up

style['WebkitBackfaceVisibility'] = 'hidden';
Expand Down
56 changes: 24 additions & 32 deletions src/util/scroll-view.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@

import { assert } from './util';
import { App } from '../components/app/app';
import { DomController, DomCallback } from '../platform/dom-controller';
import { Platform, EventListenerOptions } from '../platform/platform';
import { pointerCoord } from './dom';
Expand All @@ -12,11 +13,11 @@ export class ScrollView {
onScroll: (ev: ScrollEvent) => void;
onScrollEnd: (ev: ScrollEvent) => void;
initialized: boolean = false;
enabled: boolean = false;
eventsEnabled: boolean = false;
contentTop: number;
contentBottom: number;

private _el: HTMLElement;
_el: HTMLElement;
private _js: boolean;
private _t: number = 0;
private _l: number = 0;
Expand All @@ -25,6 +26,7 @@ export class ScrollView {


constructor(
private _app: App,
private _plt: Platform,
private _dom: DomController,
virtualScrollEventAssist: boolean
Expand Down Expand Up @@ -60,35 +62,19 @@ export class ScrollView {

if (!this.initialized) {
this.initialized = true;

if (this.enabled) {
this.enable();
}
}
}

setEnabled() {
if (!this.enabled) {
this.enabled = true;
if (this.initialized) {
this.enable();
if (this._js) {
this.enableJsScroll();
} else {
this.enableNativeScrolling();
}
}
}

enable() {
assert(this.initialized, 'scroll must be initialized');
assert(this.enabled, 'scroll-view must be enabled');
assert(this._el, 'scroll-view, element can not be null');

if (this._js) {
this.enableJsScroll();
} else {
this.enableNativeScrolling();
}
}

private enableNativeScrolling() {
assert(this.onScrollStart, 'onScrollStart is not defined');
assert(this.onScroll, 'onScroll is not defined');
assert(this.onScrollEnd, 'onScrollEnd is not defined');

this._js = false;
if (!this._el) {
return;
Expand All @@ -101,6 +87,14 @@ export class ScrollView {
const positions: number[] = [];

function scrollCallback(scrollEvent: UIEvent) {
// remind the app that it's currently scrolling
self._app.setScrolling();

// if events are disabled, we do nothing
if (!self.eventsEnabled) {
return;
}

ev.timeStamp = scrollEvent.timeStamp;
// Event.timeStamp is 0 in firefox
if (!ev.timeStamp) {
Expand Down Expand Up @@ -151,13 +145,12 @@ export class ScrollView {

if (startPos !== endPos) {
// compute relative movement between these two points
var timeOffset = (positions[endPos] - positions[startPos]);
var movedTop = (positions[startPos - 2] - positions[endPos - 2]);
var movedLeft = (positions[startPos - 1] - positions[endPos - 1]);

var factor = FRAME_MS / (positions[endPos] - positions[startPos]);
// based on XXms compute the movement to apply for each render step
ev.velocityY = ((movedTop / timeOffset) * FRAME_MS);
ev.velocityX = ((movedLeft / timeOffset) * FRAME_MS);
ev.velocityY = movedTop * factor;
ev.velocityX = movedLeft * factor;

// figure out which direction we're scrolling
ev.directionY = (movedTop > 0 ? 'up' : 'down');
Expand Down Expand Up @@ -546,11 +539,10 @@ export class ScrollView {
this._endTmr && this._dom.cancel(this._endTmr);
this._lsn && this._lsn();

this.onScrollStart = this.onScroll = this.onScrollEnd = null;

let ev = this.ev;
ev.domWrite = ev.contentElement = ev.fixedElement = ev.scrollElement = ev.headerElement = null;
this._lsn = this._el = this._dom = this.ev = ev = null;
this.onScrollStart = this.onScroll = this.onScrollEnd = null;
}

}
Expand Down