fix back button in spa not working between two pages that both have hash fragments

This commit is contained in:
Jacky Zhao 2023-08-17 01:34:50 -07:00
parent 509e8d499c
commit e7fde5f937
4 changed files with 15 additions and 11 deletions

View File

@ -4,9 +4,6 @@ draft: true
## todo ## todo
- static icon path (in head) never gets updated
- do we update relative links on spa?
- back button with anchors / popovers + spa is broken
- debounce cfg rebuild on large repos - debounce cfg rebuild on large repos
- investigate content rebuild triggering multiple times even when debounced, causing an esbuild deadlock - investigate content rebuild triggering multiple times even when debounced, causing an esbuild deadlock
- dereference symlink for npx quartz sync - dereference symlink for npx quartz sync

View File

@ -179,7 +179,6 @@ async function renderGraph(container: string, slug: CanonicalSlug) {
const neighbourNodes = d3 const neighbourNodes = d3
.selectAll<HTMLElement, NodeData>(".node") .selectAll<HTMLElement, NodeData>(".node")
.filter((d) => neighbours.includes(d.id)) .filter((d) => neighbours.includes(d.id))
console.log(neighbourNodes)
const currentId = d.id const currentId = d.id
const linkNodes = d3 const linkNodes = d3
.selectAll(".link") .selectAll(".link")

View File

@ -148,7 +148,6 @@ document.addEventListener("nav", async (e: unknown) => {
async function onType(e: HTMLElementEventMap["input"]) { async function onType(e: HTMLElementEventMap["input"]) {
const term = (e.target as HTMLInputElement).value const term = (e.target as HTMLInputElement).value
const searchResults = (await index?.searchAsync(term, numSearchResults)) ?? [] const searchResults = (await index?.searchAsync(term, numSearchResults)) ?? []
console.log(searchResults)
const getByField = (field: string): number[] => { const getByField = (field: string): number[] => {
const results = searchResults.filter((x) => x.field === field) const results = searchResults.filter((x) => x.field === field)
return results.length === 0 ? [] : ([...results[0].result] as number[]) return results.length === 0 ? [] : ([...results[0].result] as number[])

View File

@ -46,10 +46,6 @@ async function navigate(url: URL, isBack: boolean = false) {
}) })
if (!contents) return if (!contents) return
if (!isBack) {
history.pushState({}, "", url)
window.scrollTo({ top: 0 })
}
const html = p.parseFromString(contents, "text/html") const html = p.parseFromString(contents, "text/html")
let title = html.querySelector("title")?.textContent let title = html.querySelector("title")?.textContent
@ -65,8 +61,20 @@ async function navigate(url: URL, isBack: boolean = false) {
announcer.dataset.persist = "" announcer.dataset.persist = ""
html.body.appendChild(announcer) html.body.appendChild(announcer)
// morph body
micromorph(document.body, html.body) micromorph(document.body, html.body)
// scroll into place and add history
if (!isBack) {
history.pushState({}, "", url)
if (url.hash) {
const el = document.getElementById(url.hash.substring(1))
el?.scrollIntoView()
} else {
window.scrollTo({ top: 0 })
}
}
// now, patch head // now, patch head
const elementsToRemove = document.head.querySelectorAll(":not([spa-preserve])") const elementsToRemove = document.head.querySelectorAll(":not([spa-preserve])")
elementsToRemove.forEach((el) => el.remove()) elementsToRemove.forEach((el) => el.remove())
@ -92,8 +100,9 @@ function createRouter() {
} }
}) })
window.addEventListener("popstate", () => { window.addEventListener("popstate", (event) => {
if (window.location.hash) return const { url } = getOpts(event) ?? {}
if (window.location.hash && window.location.pathname === url?.pathname) return
try { try {
navigate(new URL(window.location.toString()), true) navigate(new URL(window.location.toString()), true)
} catch (e) { } catch (e) {