Skip to content

Commit d9a7652

Browse files
committed
fix(content): scroll listener is auto enabled
fixes #10938
1 parent 54acc74 commit d9a7652

File tree

5 files changed

+53
-47
lines changed

5 files changed

+53
-47
lines changed

src/components/content/content.ts

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ChangeDetectionStrategy, Component, ElementRef, EventEmitter, Input, NgZone, OnDestroy, Optional, Output, Renderer, ViewChild, ViewEncapsulation } from '@angular/core';
1+
import { AfterViewInit, ChangeDetectionStrategy, Component, ElementRef, EventEmitter, Input, NgZone, OnDestroy, Optional, Output, Renderer, ViewChild, ViewEncapsulation } from '@angular/core';
22

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

1919

20+
export class EventEmitterProxy<T> extends EventEmitter<T> {
21+
onSubscribe: Function;
22+
subscribe(generatorOrNext?: any, error?: any, complete?: any): any {
23+
this.onSubscribe();
24+
return super.subscribe(generatorOrNext, error, complete);
25+
}
26+
}
27+
2028
/**
2129
* @name Content
2230
* @description
@@ -125,7 +133,7 @@ export { ScrollEvent } from '../../util/scroll-view';
125133
changeDetection: ChangeDetectionStrategy.OnPush,
126134
encapsulation: ViewEncapsulation.None
127135
})
128-
export class Content extends Ion implements OnDestroy {
136+
export class Content extends Ion implements OnDestroy, AfterViewInit {
129137
/** @internal */
130138
_cTop: number;
131139
/** @internal */
@@ -312,17 +320,17 @@ export class Content extends Ion implements OnDestroy {
312320
/**
313321
* @output {ScrollEvent} Emitted when the scrolling first starts.
314322
*/
315-
@Output() ionScrollStart: EventEmitter<ScrollEvent> = new EventEmitter<ScrollEvent>();
323+
@Output() ionScrollStart: EventEmitterProxy<ScrollEvent> = new EventEmitterProxy<ScrollEvent>();
316324

317325
/**
318326
* @output {ScrollEvent} Emitted on every scroll event.
319327
*/
320-
@Output() ionScroll: EventEmitter<ScrollEvent> = new EventEmitter<ScrollEvent>();
328+
@Output() ionScroll: EventEmitterProxy<ScrollEvent> = new EventEmitterProxy<ScrollEvent>();
321329

322330
/**
323331
* @output {ScrollEvent} Emitted when scrolling ends.
324332
*/
325-
@Output() ionScrollEnd: EventEmitter<ScrollEvent> = new EventEmitter<ScrollEvent>();
333+
@Output() ionScrollEnd: EventEmitterProxy<ScrollEvent> = new EventEmitterProxy<ScrollEvent>();
326334

327335

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

350+
let enableScrollListener = this.enableScrollListener.bind(this);
351+
this.ionScroll.onSubscribe = enableScrollListener;
352+
this.ionScrollStart.onSubscribe = enableScrollListener;
353+
this.ionScrollEnd.onSubscribe = enableScrollListener;
354+
342355
this.statusbarPadding = config.getBoolean('statusbarPadding', false);
343356
this._imgReqBfr = config.getNumber('imgRequestBuffer', 1400);
344357
this._imgRndBfr = config.getNumber('imgRenderBuffer', 400);
@@ -348,7 +361,8 @@ export class Content extends Ion implements OnDestroy {
348361
// goal is to completely remove this when iOS
349362
// fully supports scroll events
350363
// listen to JS scroll events
351-
this._scroll = new ScrollView(_plt, _dom, config.getBoolean('virtualScrollEventAssist'));
364+
const jsScroll = config.getBoolean('virtualScrollEventAssist');
365+
this._scroll = new ScrollView(_app, _plt, _dom, jsScroll);
352366

353367
while (navCtrl) {
354368
if (isTabs(<any>navCtrl)) {
@@ -383,7 +397,7 @@ export class Content extends Ion implements OnDestroy {
383397
/**
384398
* @hidden
385399
*/
386-
enableScrollListener() {
400+
ngAfterViewInit() {
387401
assert(this.getFixedElement(), 'fixed element was not found');
388402
assert(this.getScrollElement(), 'scroll element was not found');
389403

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

399413
// subscribe to every scroll move
400414
scroll.onScroll = (ev) => {
401-
// remind the app that it's currently scrolling
402-
this._app.setScrolling();
403-
404415
// emit to all of our other friends things be scrolling
405416
this.ionScroll.emit(ev);
406417

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

414425
this.imgsUpdate();
415426
};
427+
}
416428

417-
scroll.setEnabled();
429+
/**
430+
* @hidden
431+
*/
432+
enableScrollListener() {
433+
this._scroll.eventsEnabled = true;
418434
}
419435

420436
/**

src/components/infinite-scroll/infinite-scroll.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,6 @@ export class InfiniteScroll {
371371
if (shouldListen) {
372372
if (!this._scLsn) {
373373
this._scLsn = this._content.ionScroll.subscribe(this._onScroll.bind(this));
374-
this._content.enableScrollListener();
375374
}
376375
} else {
377376
this._scLsn && this._scLsn.unsubscribe();

src/components/virtual-scroll/virtual-scroll.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -709,7 +709,6 @@ export class VirtualScroll implements DoCheck, AfterContentInit, OnDestroy {
709709
this._resizeSub = this._plt.resize.subscribe(this.resize.bind(this));
710710
this._scrollSub = this._content.ionScroll.subscribe(this.scrollUpdate.bind(this));
711711
this._scrollEndSub = this._content.ionScrollEnd.subscribe(this.scrollEnd.bind(this));
712-
this._content.enableScrollListener();
713712
}
714713
}
715714

src/util/events.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,8 @@ export function setupEvents(plt: Platform, dom: DomController): Events {
137137
let contentEle = <any>el.closest('.scroll-content');
138138
if (contentEle) {
139139
var style = contentEle.style;
140-
var scroll = new ScrollView(plt, dom, false);
141-
scroll.init(contentEle, 0, 0);
140+
var scroll = new ScrollView(null, plt, dom, false);
141+
scroll._el = contentEle;
142142
// We need to stop scrolling if it's happening and scroll up
143143

144144
style['WebkitBackfaceVisibility'] = 'hidden';

src/util/scroll-view.ts

Lines changed: 24 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11

22
import { assert } from './util';
3+
import { App } from '../components/app/app';
34
import { DomController, DomCallback } from '../platform/dom-controller';
45
import { Platform, EventListenerOptions } from '../platform/platform';
56
import { pointerCoord } from './dom';
@@ -12,11 +13,11 @@ export class ScrollView {
1213
onScroll: (ev: ScrollEvent) => void;
1314
onScrollEnd: (ev: ScrollEvent) => void;
1415
initialized: boolean = false;
15-
enabled: boolean = false;
16+
eventsEnabled: boolean = false;
1617
contentTop: number;
1718
contentBottom: number;
1819

19-
private _el: HTMLElement;
20+
_el: HTMLElement;
2021
private _js: boolean;
2122
private _t: number = 0;
2223
private _l: number = 0;
@@ -25,6 +26,7 @@ export class ScrollView {
2526

2627

2728
constructor(
29+
private _app: App,
2830
private _plt: Platform,
2931
private _dom: DomController,
3032
virtualScrollEventAssist: boolean
@@ -60,35 +62,19 @@ export class ScrollView {
6062

6163
if (!this.initialized) {
6264
this.initialized = true;
63-
64-
if (this.enabled) {
65-
this.enable();
66-
}
67-
}
68-
}
69-
70-
setEnabled() {
71-
if (!this.enabled) {
72-
this.enabled = true;
73-
if (this.initialized) {
74-
this.enable();
65+
if (this._js) {
66+
this.enableJsScroll();
67+
} else {
68+
this.enableNativeScrolling();
7569
}
7670
}
7771
}
7872

79-
enable() {
80-
assert(this.initialized, 'scroll must be initialized');
81-
assert(this.enabled, 'scroll-view must be enabled');
82-
assert(this._el, 'scroll-view, element can not be null');
83-
84-
if (this._js) {
85-
this.enableJsScroll();
86-
} else {
87-
this.enableNativeScrolling();
88-
}
89-
}
90-
9173
private enableNativeScrolling() {
74+
assert(this.onScrollStart, 'onScrollStart is not defined');
75+
assert(this.onScroll, 'onScroll is not defined');
76+
assert(this.onScrollEnd, 'onScrollEnd is not defined');
77+
9278
this._js = false;
9379
if (!this._el) {
9480
return;
@@ -101,6 +87,14 @@ export class ScrollView {
10187
const positions: number[] = [];
10288

10389
function scrollCallback(scrollEvent: UIEvent) {
90+
// remind the app that it's currently scrolling
91+
self._app.setScrolling();
92+
93+
// if events are disabled, we do nothing
94+
if (!self.eventsEnabled) {
95+
return;
96+
}
97+
10498
ev.timeStamp = scrollEvent.timeStamp;
10599
// Event.timeStamp is 0 in firefox
106100
if (!ev.timeStamp) {
@@ -151,13 +145,12 @@ export class ScrollView {
151145

152146
if (startPos !== endPos) {
153147
// compute relative movement between these two points
154-
var timeOffset = (positions[endPos] - positions[startPos]);
155148
var movedTop = (positions[startPos - 2] - positions[endPos - 2]);
156149
var movedLeft = (positions[startPos - 1] - positions[endPos - 1]);
157-
150+
var factor = FRAME_MS / (positions[endPos] - positions[startPos]);
158151
// based on XXms compute the movement to apply for each render step
159-
ev.velocityY = ((movedTop / timeOffset) * FRAME_MS);
160-
ev.velocityX = ((movedLeft / timeOffset) * FRAME_MS);
152+
ev.velocityY = movedTop * factor;
153+
ev.velocityX = movedLeft * factor;
161154

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

549-
this.onScrollStart = this.onScroll = this.onScrollEnd = null;
550-
551542
let ev = this.ev;
552543
ev.domWrite = ev.contentElement = ev.fixedElement = ev.scrollElement = ev.headerElement = null;
553544
this._lsn = this._el = this._dom = this.ev = ev = null;
545+
this.onScrollStart = this.onScroll = this.onScrollEnd = null;
554546
}
555547

556548
}

0 commit comments

Comments
 (0)