fix(common): Prefer to use pageXOffset / pageYOffset instance of scrollX / scrollY (#28262)
This fix ensures a better cross-browser compatibility. This fix has been used for angular.io. PR Close #28262
This commit is contained in:
parent
be998e830b
commit
b1d300dc26
|
@ -24,7 +24,7 @@ export class ScrollService implements OnDestroy {
|
|||
poppedStateScrollPosition: ScrollPosition|null = null;
|
||||
// Whether the browser supports the necessary features for manual scroll restoration.
|
||||
supportManualScrollRestoration: boolean = !!window && ('scrollTo' in window) &&
|
||||
('scrollX' in window) && ('scrollY' in window) && isScrollRestorationWritable();
|
||||
('pageXOffset' in window) && isScrollRestorationWritable();
|
||||
|
||||
// Offset from the top of the document to bottom of any static elements
|
||||
// at the top (e.g. toolbar) + some margin
|
||||
|
|
|
@ -89,7 +89,7 @@ export class BrowserViewportScroller implements ViewportScroller {
|
|||
*/
|
||||
getScrollPosition(): [number, number] {
|
||||
if (this.supportsScrolling()) {
|
||||
return [this.window.scrollX, this.window.scrollY];
|
||||
return [this.window.pageXOffset, this.window.pageYOffset];
|
||||
} else {
|
||||
return [0, 0];
|
||||
}
|
||||
|
@ -149,7 +149,7 @@ export class BrowserViewportScroller implements ViewportScroller {
|
|||
*/
|
||||
private supportScrollRestoration(): boolean {
|
||||
try {
|
||||
if (!this.window || !this.window.scrollTo) {
|
||||
if (!this.supportsScrolling()) {
|
||||
return false;
|
||||
}
|
||||
// The `scrollRestoration` property could be on the `history` instance or its prototype.
|
||||
|
@ -166,7 +166,7 @@ export class BrowserViewportScroller implements ViewportScroller {
|
|||
|
||||
private supportsScrolling(): boolean {
|
||||
try {
|
||||
return !!this.window.scrollTo;
|
||||
return !!this.window && !!this.window.scrollTo && 'pageXOffset' in this.window;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -15,7 +15,8 @@ describe('BrowserViewportScroller', () => {
|
|||
let windowSpy: any;
|
||||
|
||||
beforeEach(() => {
|
||||
windowSpy = jasmine.createSpyObj('window', ['history', 'scrollTo']);
|
||||
windowSpy =
|
||||
jasmine.createSpyObj('window', ['history', 'scrollTo', 'pageXOffset', 'pageYOffset']);
|
||||
windowSpy.history.scrollRestoration = 'auto';
|
||||
documentSpy = jasmine.createSpyObj('document', ['getElementById', 'getElementsByName']);
|
||||
scroller = new BrowserViewportScroller(documentSpy, windowSpy, null!);
|
||||
|
|
|
@ -348,27 +348,24 @@ describe('bootstrap', () => {
|
|||
await router.navigateByUrl('/aa');
|
||||
window.scrollTo(0, 5000);
|
||||
|
||||
// IE 11 uses non-standard pageYOffset instead of scrollY
|
||||
const getScrollY = () => window.scrollY !== undefined ? window.scrollY : window.pageYOffset;
|
||||
|
||||
await router.navigateByUrl('/fail');
|
||||
expect(getScrollY()).toEqual(5000);
|
||||
expect(window.pageYOffset).toEqual(5000);
|
||||
|
||||
await router.navigateByUrl('/bb');
|
||||
window.scrollTo(0, 3000);
|
||||
|
||||
expect(getScrollY()).toEqual(3000);
|
||||
expect(window.pageYOffset).toEqual(3000);
|
||||
|
||||
await router.navigateByUrl('/cc');
|
||||
expect(getScrollY()).toEqual(0);
|
||||
expect(window.pageYOffset).toEqual(0);
|
||||
|
||||
await router.navigateByUrl('/aa#marker2');
|
||||
expect(getScrollY()).toBeGreaterThanOrEqual(5900);
|
||||
expect(getScrollY()).toBeLessThan(6000); // offset
|
||||
expect(window.pageYOffset).toBeGreaterThanOrEqual(5900);
|
||||
expect(window.pageYOffset).toBeLessThan(6000); // offset
|
||||
|
||||
await router.navigateByUrl('/aa#marker3');
|
||||
expect(getScrollY()).toBeGreaterThanOrEqual(8900);
|
||||
expect(getScrollY()).toBeLessThan(9000);
|
||||
expect(window.pageYOffset).toBeGreaterThanOrEqual(8900);
|
||||
expect(window.pageYOffset).toBeLessThan(9000);
|
||||
done();
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in New Issue