fix back button in spa not working between two pages that both have hash fragments
This commit is contained in:
		
							parent
							
								
									58d9dc0528
								
							
						
					
					
						commit
						07a327e05a
					
				| @ -4,9 +4,6 @@ draft: true | ||||
| 
 | ||||
| ## 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 | ||||
|   - investigate content rebuild triggering multiple times even when debounced, causing an esbuild deadlock | ||||
| - dereference symlink for npx quartz sync | ||||
|  | ||||
| @ -179,7 +179,6 @@ async function renderGraph(container: string, slug: CanonicalSlug) { | ||||
|       const neighbourNodes = d3 | ||||
|         .selectAll<HTMLElement, NodeData>(".node") | ||||
|         .filter((d) => neighbours.includes(d.id)) | ||||
|       console.log(neighbourNodes) | ||||
|       const currentId = d.id | ||||
|       const linkNodes = d3 | ||||
|         .selectAll(".link") | ||||
|  | ||||
| @ -148,7 +148,6 @@ document.addEventListener("nav", async (e: unknown) => { | ||||
|   async function onType(e: HTMLElementEventMap["input"]) { | ||||
|     const term = (e.target as HTMLInputElement).value | ||||
|     const searchResults = (await index?.searchAsync(term, numSearchResults)) ?? [] | ||||
|     console.log(searchResults) | ||||
|     const getByField = (field: string): number[] => { | ||||
|       const results = searchResults.filter((x) => x.field === field) | ||||
|       return results.length === 0 ? [] : ([...results[0].result] as number[]) | ||||
|  | ||||
| @ -46,10 +46,6 @@ async function navigate(url: URL, isBack: boolean = false) { | ||||
|     }) | ||||
| 
 | ||||
|   if (!contents) return | ||||
|   if (!isBack) { | ||||
|     history.pushState({}, "", url) | ||||
|     window.scrollTo({ top: 0 }) | ||||
|   } | ||||
| 
 | ||||
|   const html = p.parseFromString(contents, "text/html") | ||||
|   let title = html.querySelector("title")?.textContent | ||||
| @ -65,8 +61,20 @@ async function navigate(url: URL, isBack: boolean = false) { | ||||
|   announcer.dataset.persist = "" | ||||
|   html.body.appendChild(announcer) | ||||
| 
 | ||||
|   // morph 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
 | ||||
|   const elementsToRemove = document.head.querySelectorAll(":not([spa-preserve])") | ||||
|   elementsToRemove.forEach((el) => el.remove()) | ||||
| @ -92,8 +100,9 @@ function createRouter() { | ||||
|       } | ||||
|     }) | ||||
| 
 | ||||
|     window.addEventListener("popstate", () => { | ||||
|       if (window.location.hash) return | ||||
|     window.addEventListener("popstate", (event) => { | ||||
|       const { url } = getOpts(event) ?? {} | ||||
|       if (window.location.hash && window.location.pathname === url?.pathname) return | ||||
|       try { | ||||
|         navigate(new URL(window.location.toString()), true) | ||||
|       } catch (e) { | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user