mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-21 21:15:24 +08:00
fix(scroll): scroll issues in UIWebView
fixes #11081 fixes #10976 fixes #10966 fixes #10936 fixes #11051 fixes #10889
This commit is contained in:
@ -349,7 +349,7 @@ export class Content extends Ion implements OnDestroy, AfterViewInit {
|
|||||||
) {
|
) {
|
||||||
super(config, elementRef, renderer, 'content');
|
super(config, elementRef, renderer, 'content');
|
||||||
|
|
||||||
let enableScrollListener = this.enableScrollListener.bind(this);
|
const enableScrollListener = () => this._scroll.enableEvents();
|
||||||
this.ionScroll.onSubscribe = enableScrollListener;
|
this.ionScroll.onSubscribe = enableScrollListener;
|
||||||
this.ionScrollStart.onSubscribe = enableScrollListener;
|
this.ionScrollStart.onSubscribe = enableScrollListener;
|
||||||
this.ionScrollEnd.onSubscribe = enableScrollListener;
|
this.ionScrollEnd.onSubscribe = enableScrollListener;
|
||||||
@ -359,12 +359,7 @@ export class Content extends Ion implements OnDestroy, AfterViewInit {
|
|||||||
this._imgRndBfr = config.getNumber('imgRenderBuffer', 400);
|
this._imgRndBfr = config.getNumber('imgRenderBuffer', 400);
|
||||||
this._imgVelMax = config.getNumber('imgVelocityMax', 3);
|
this._imgVelMax = config.getNumber('imgVelocityMax', 3);
|
||||||
|
|
||||||
// use JS scrolling for iOS UIWebView
|
this._scroll = new ScrollView(_app, _plt, _dom);
|
||||||
// goal is to completely remove this when iOS
|
|
||||||
// fully supports scroll events
|
|
||||||
// listen to JS scroll events
|
|
||||||
const jsScroll = config.getBoolean('virtualScrollEventAssist');
|
|
||||||
this._scroll = new ScrollView(_app, _plt, _dom, jsScroll);
|
|
||||||
|
|
||||||
while (navCtrl) {
|
while (navCtrl) {
|
||||||
if (isTabs(<any>navCtrl)) {
|
if (isTabs(<any>navCtrl)) {
|
||||||
@ -431,8 +426,8 @@ export class Content extends Ion implements OnDestroy, AfterViewInit {
|
|||||||
/**
|
/**
|
||||||
* @hidden
|
* @hidden
|
||||||
*/
|
*/
|
||||||
enableScrollListener() {
|
enableJsScroll() {
|
||||||
this._scroll.eventsEnabled = true;
|
this._scroll.enableJsScroll(this._cTop, this._cBottom);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -706,6 +706,14 @@ export class VirtualScroll implements DoCheck, AfterContentInit, OnDestroy {
|
|||||||
private _listeners() {
|
private _listeners() {
|
||||||
assert(!this._scrollSub, '_listeners was already called');
|
assert(!this._scrollSub, '_listeners was already called');
|
||||||
if (!this._scrollSub) {
|
if (!this._scrollSub) {
|
||||||
|
if (this._config.getBoolean('virtualScrollEventAssist')) {
|
||||||
|
// use JS scrolling for iOS UIWebView
|
||||||
|
// goal is to completely remove this when iOS
|
||||||
|
// fully supports scroll events
|
||||||
|
// listen to JS scroll events
|
||||||
|
this._content.enableJsScroll();
|
||||||
|
}
|
||||||
|
|
||||||
this._resizeSub = this._plt.resize.subscribe(this.resize.bind(this));
|
this._resizeSub = this._plt.resize.subscribe(this.resize.bind(this));
|
||||||
this._scrollSub = this._content.ionScroll.subscribe(this.scrollUpdate.bind(this));
|
this._scrollSub = this._content.ionScroll.subscribe(this.scrollUpdate.bind(this));
|
||||||
this._scrollEndSub = this._content.ionScrollEnd.subscribe(this.scrollEnd.bind(this));
|
this._scrollEndSub = this._content.ionScrollEnd.subscribe(this.scrollEnd.bind(this));
|
||||||
|
@ -137,7 +137,7 @@ export function setupEvents(plt: Platform, dom: DomController): Events {
|
|||||||
let contentEle = <any>el.closest('.scroll-content');
|
let contentEle = <any>el.closest('.scroll-content');
|
||||||
if (contentEle) {
|
if (contentEle) {
|
||||||
var style = contentEle.style;
|
var style = contentEle.style;
|
||||||
var scroll = new ScrollView(null, plt, dom, false);
|
var scroll = new ScrollView(null, plt, dom);
|
||||||
scroll._el = contentEle;
|
scroll._el = contentEle;
|
||||||
// We need to stop scrolling if it's happening and scroll up
|
// We need to stop scrolling if it's happening and scroll up
|
||||||
|
|
||||||
|
@ -14,11 +14,10 @@ export class ScrollView {
|
|||||||
onScroll: (ev: ScrollEvent) => void;
|
onScroll: (ev: ScrollEvent) => void;
|
||||||
onScrollEnd: (ev: ScrollEvent) => void;
|
onScrollEnd: (ev: ScrollEvent) => void;
|
||||||
initialized: boolean = false;
|
initialized: boolean = false;
|
||||||
eventsEnabled: boolean = false;
|
|
||||||
contentTop: number;
|
|
||||||
contentBottom: number;
|
|
||||||
|
|
||||||
_el: HTMLElement;
|
_el: HTMLElement;
|
||||||
|
|
||||||
|
|
||||||
|
private _eventsEnabled = false;
|
||||||
private _js: boolean;
|
private _js: boolean;
|
||||||
private _t: number = 0;
|
private _t: number = 0;
|
||||||
private _l: number = 0;
|
private _l: number = 0;
|
||||||
@ -28,10 +27,8 @@ export class ScrollView {
|
|||||||
constructor(
|
constructor(
|
||||||
private _app: App,
|
private _app: App,
|
||||||
private _plt: Platform,
|
private _plt: Platform,
|
||||||
private _dom: DomController,
|
private _dom: DomController
|
||||||
virtualScrollEventAssist: boolean
|
|
||||||
) {
|
) {
|
||||||
this._js = virtualScrollEventAssist;
|
|
||||||
this.ev = {
|
this.ev = {
|
||||||
timeStamp: 0,
|
timeStamp: 0,
|
||||||
scrollTop: 0,
|
scrollTop: 0,
|
||||||
@ -57,19 +54,20 @@ export class ScrollView {
|
|||||||
init(ele: HTMLElement, contentTop: number, contentBottom: number) {
|
init(ele: HTMLElement, contentTop: number, contentBottom: number) {
|
||||||
assert(ele, 'scroll-view, element can not be null');
|
assert(ele, 'scroll-view, element can not be null');
|
||||||
this._el = ele;
|
this._el = ele;
|
||||||
this.contentTop = contentTop;
|
|
||||||
this.contentBottom = contentBottom;
|
|
||||||
|
|
||||||
if (!this.initialized) {
|
if (!this.initialized) {
|
||||||
this.initialized = true;
|
this.initialized = true;
|
||||||
if (this._js) {
|
if (this._js) {
|
||||||
this.enableJsScroll();
|
this.enableJsScroll(contentTop, contentBottom);
|
||||||
} else {
|
} else {
|
||||||
this.enableNativeScrolling();
|
this.enableNativeScrolling();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enableEvents() {
|
||||||
|
this._eventsEnabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
private enableNativeScrolling() {
|
private enableNativeScrolling() {
|
||||||
assert(this.onScrollStart, 'onScrollStart is not defined');
|
assert(this.onScrollStart, 'onScrollStart is not defined');
|
||||||
assert(this.onScroll, 'onScroll is not defined');
|
assert(this.onScroll, 'onScroll is not defined');
|
||||||
@ -91,7 +89,7 @@ export class ScrollView {
|
|||||||
self._app.setScrolling();
|
self._app.setScrolling();
|
||||||
|
|
||||||
// if events are disabled, we do nothing
|
// if events are disabled, we do nothing
|
||||||
if (!self.eventsEnabled) {
|
if (!self._eventsEnabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -200,7 +198,7 @@ export class ScrollView {
|
|||||||
* inertia then this can be burned to the ground. iOS's more modern
|
* inertia then this can be burned to the ground. iOS's more modern
|
||||||
* WKWebView does not have this issue, only UIWebView does.
|
* WKWebView does not have this issue, only UIWebView does.
|
||||||
*/
|
*/
|
||||||
enableJsScroll() {
|
enableJsScroll(contentTop: number, contentBottom: number) {
|
||||||
const self = this;
|
const self = this;
|
||||||
self._js = true;
|
self._js = true;
|
||||||
const ele = self._el;
|
const ele = self._el;
|
||||||
@ -219,7 +217,7 @@ export class ScrollView {
|
|||||||
function setMax() {
|
function setMax() {
|
||||||
if (!max) {
|
if (!max) {
|
||||||
// ******** DOM READ ****************
|
// ******** DOM READ ****************
|
||||||
max = ele.scrollHeight - ele.parentElement.offsetHeight + self.contentTop + self.contentBottom;
|
max = ele.scrollHeight - ele.parentElement.offsetHeight + contentTop + contentBottom;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user