wait for page to load befor scroll to anchor

This commit is contained in:
bniwredyc 2023-04-03 16:22:59 +02:00
parent 71fb5c5276
commit dace7daca8
3 changed files with 63 additions and 21 deletions

View File

@ -7,6 +7,7 @@ import { useRouter } from '../stores/router'
import { Loading } from '../components/_shared/Loading'
import { ReactionsProvider } from '../context/reactions'
import { FullArticle } from '../components/Article/FullArticle'
import { setPageLoadManagerPromise } from '../utils/pageLoadManager'
export const ArticlePage = (props: PageProps) => {
const shouts = props.article ? [props.article] : []
@ -33,7 +34,9 @@ export const ArticlePage = (props: PageProps) => {
const articleValue = articleEntities()[slug()]
if (!articleValue || !articleValue.body) {
await loadShout(slug())
const loadShoutPromise = loadShout(slug())
setPageLoadManagerPromise(loadShoutPromise)
await loadShoutPromise
}
})

View File

@ -2,6 +2,8 @@ import type { Accessor } from 'solid-js'
import { createRouter, createSearchParams } from '@nanostores/router'
import { isServer } from 'solid-js/web'
import { useStore } from '@nanostores/solid'
import { loadShoutPromise } from './zine/articles'
import { getPageLoadManagerPromise } from '../utils/pageLoadManager'
export const ROUTES = {
home: '/',
@ -54,7 +56,27 @@ const checkOpenOnClient = (link: HTMLAnchorElement, event) => {
)
}
const handleClientRouteLinkClick = (event) => {
const scrollToHash = (hash: string) => {
let selector = hash
if (/^#\d+/.test(selector)) {
// id="1" fix
// https://stackoverflow.com/questions/20306204/using-queryselector-with-ids-that-are-numbers
selector = `[id="${selector.replace('#', '')}"]`
}
const anchor = document.querySelector(selector)
const headerOffset = 80 // 100px for header
const elementPosition = anchor ? anchor.getBoundingClientRect().top : 0
const newScrollTop = elementPosition + window.scrollY - headerOffset
window.scrollTo({
top: newScrollTop,
behavior: 'smooth'
})
}
const handleClientRouteLinkClick = async (event) => {
const link = event.target.closest('a')
if (!checkOpenOnClient(link, event)) {
@ -77,31 +99,37 @@ const handleClientRouteLinkClick = (event) => {
searchParamsStore.open(params)
}
if (url.hash) {
let selector = url.hash
if (/^#\d+/.test(selector)) {
// id="1" fix
// https://stackoverflow.com/questions/20306204/using-queryselector-with-ids-that-are-numbers
selector = `[id="${selector.replace('#', '')}"]`
}
const anchor = document.querySelector(selector)
const headerOffset = 80 // 100px for header
const elementPosition = anchor ? anchor.getBoundingClientRect().top : 0
const newScrollTop = elementPosition + window.scrollY - headerOffset
if (!url.hash) {
window.scrollTo({
top: newScrollTop,
behavior: 'smooth'
top: 0,
left: 0
})
return
}
window.scrollTo({
top: 0,
left: 0
await getPageLoadManagerPromise()
const images = document.querySelectorAll('img')
let imagesLoaded = 0
const imageLoadEventHandler = () => {
imagesLoaded++
if (imagesLoaded === images.length) {
scrollToHash(url.hash)
images.forEach((image) => image.removeEventListener('load', imageLoadEventHandler))
images.forEach((image) => image.removeEventListener('error', imageLoadEventHandler))
}
}
images.forEach((image) => {
if (image.complete) {
imagesLoaded++
}
image.addEventListener('load', imageLoadEventHandler)
image.addEventListener('error', imageLoadEventHandler)
})
}

View File

@ -0,0 +1,11 @@
const pageLoadManager: {
promise: Promise<any>
} = { promise: Promise.resolve() }
export const getPageLoadManagerPromise = () => {
return pageLoadManager.promise
}
export const setPageLoadManagerPromise = (promise: Promise<any>) => {
pageLoadManager.promise = promise
}