Skip to content

Commit

Permalink
[1.x] Fix resetScrollPositions and restoreScrollPositions router …
Browse files Browse the repository at this point in the history
…methods (#1980)

* Add nextFrame function

* Format

* Fix scroll-to-top flash when leaving page

Closes #1803

* Wrap resetScrollPositions in nextFrame

* Wrap restoreScrollPositions in nextFrame
  • Loading branch information
pedroborges committed Sep 19, 2024
1 parent fcc8cde commit ba2099f
Showing 1 changed file with 23 additions and 16 deletions.
39 changes: 23 additions & 16 deletions packages/core/src/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ import { hrefToUrl, mergeDataIntoQueryString, urlWithoutHash } from './url'

const isServer = typeof window === 'undefined'
const cloneSerializable = <T>(obj: T): T => JSON.parse(JSON.stringify(obj))
const nextFrame = (callback: () => void) => {
requestAnimationFrame(() => {
requestAnimationFrame(callback)
})
}

export class Router {
protected page!: Page
Expand Down Expand Up @@ -87,7 +92,7 @@ export class Router {
if (!this.page.url.includes(hash)) {
this.page.url += hash
}
this.setPage(page, { preserveScroll: true ,preserveState: true }).then(() => fireNavigateEvent(page))
this.setPage(page, { preserveScroll: true, preserveState: true }).then(() => fireNavigateEvent(page))
}

protected setupEventListeners(): void {
Expand Down Expand Up @@ -121,25 +126,27 @@ export class Router {
}

protected resetScrollPositions(): void {
window.scrollTo(0, 0)
this.scrollRegions().forEach((region) => {
if (typeof region.scrollTo === 'function') {
region.scrollTo(0, 0)
} else {
region.scrollTop = 0
region.scrollLeft = 0
nextFrame(() => {
window.scrollTo(0, 0)
this.scrollRegions().forEach((region) => {
if (typeof region.scrollTo === 'function') {
region.scrollTo(0, 0)
} else {
region.scrollTop = 0
region.scrollLeft = 0
}
})
this.saveScrollPositions()
if (window.location.hash) {
document.getElementById(window.location.hash.slice(1))?.scrollIntoView()
}
})
this.saveScrollPositions()
if (window.location.hash) {
// We're using a setTimeout() here as a workaround for a bug in the React adapter where the
// rendering isn't completing fast enough, causing the anchor link to not be scrolled to.
setTimeout(() => document.getElementById(window.location.hash.slice(1))?.scrollIntoView())
}
}

protected restoreScrollPositions(): void {
if (this.page.scrollRegions) {
nextFrame(() => {
if (!this.page.scrollRegions) return

this.scrollRegions().forEach((region: Element, index: number) => {
const scrollPosition = this.page.scrollRegions[index]
if (!scrollPosition) {
Expand All @@ -151,7 +158,7 @@ export class Router {
region.scrollLeft = scrollPosition.left
}
})
}
})
}

protected isBackForwardVisit(): boolean {
Expand Down

0 comments on commit ba2099f

Please sign in to comment.