Skip to content

Commit

Permalink
scroll to id on link
Browse files Browse the repository at this point in the history
  • Loading branch information
codediodeio committed Sep 1, 2022
1 parent cbfed25 commit 108f40f
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 11 deletions.
2 changes: 1 addition & 1 deletion example/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
<body>
<div id="load-bar"></div>
<h1 id="heading">Home</h1>
<a href="/">Home</a> | <a id="about" href="/about">About</a> |
<a href="/">Home</a> | <a id="about" href="/about">About</a>

<div id="keep" flamethrower-preserve>
<article>
Expand Down
20 changes: 14 additions & 6 deletions lib/handlers.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
import { RouteChangeData } from './interfaces';

/**
* @param {} type
* scroll to top of page
* @param {string} type
* @param {string} id
* scroll to position on next page
*/
export function scrollToTop(type: string): void {
export function scrollTo(type: string, id?: string): void {
if (['link', 'go'].includes(type)) {
window.scrollTo({ top: 0 });
if (id) {
const el = document.querySelector(id);
el ? el.scrollIntoView({ behavior: 'smooth', block: 'start' }) : window.scrollTo({ top: 0 });
} else {
window.scrollTo({ top: 0 });
}
}
}
/**
Expand All @@ -16,7 +22,7 @@ export function scrollToTop(type: string): void {
*/
export function fullURL(url?: string): string {
const href = new URL(url || window.location.href).href;
return href.endsWith('/') || href.includes('.') ? href : `${href}/`;
return href.endsWith('/') || href.includes('.') || href.includes('#') ? href : `${href}/`;
}

/**
Expand Down Expand Up @@ -92,11 +98,13 @@ export function handleLinkClick(e: MouseEvent): RouteChangeData {
return { type: 'scrolled' };
}

// ID to scroll to after navigation, like /route/#some-id
const scrollId = ahref.match(/#([\w'-]+)\b/g)?.[0];
const next = fullURL(url.href);
const prev = fullURL();

// addToPushState(next);
return { type: 'link', next, prev };
return { type: 'link', next, prev, scrollId };
} else {
return { type: 'noop' };
}
Expand Down
1 change: 1 addition & 0 deletions lib/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export interface RouteChangeData {
type: 'link' | 'popstate' | 'noop' | 'disqualified' | 'scroll' | 'go' | string;
next?: string;
prev?: string;
scrollId?: string;
}

export type FlameWindow = Window & typeof globalThis & { flamethrower: Router };
Expand Down
9 changes: 5 additions & 4 deletions lib/router.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { FetchProgressEvent, FlamethrowerOptions, RouteChangeData } from './interfaces';
import { addToPushState, handleLinkClick, handlePopState, scrollToTop } from './handlers';
import { addToPushState, handleLinkClick, handlePopState, scrollTo } from './handlers';
import { mergeHead, formatNextDocument, replaceBody, runScripts } from './dom';

const defaultOpts = {
Expand Down Expand Up @@ -158,7 +158,7 @@ export class Router {
* @param {RouteChangeData} routeChangeData
* Main process for reconstructing the DOM
*/
private async reconstructDOM({ type, next, prev }: RouteChangeData): Promise<boolean> {
private async reconstructDOM({ type, next, prev, scrollId }: RouteChangeData): Promise<boolean> {
if (!this.enabled) {
this.log('router disabled');
return;
Expand Down Expand Up @@ -222,6 +222,7 @@ export class Router {
});
})
.then((stream) => new Response(stream, { headers: { 'Content-Type': 'text/html' } }));

const html = await res.text();
const nextDoc = formatNextDocument(html);

Expand All @@ -235,14 +236,14 @@ export class Router {
transition.start(() => {
replaceBody(nextDoc);
runScripts();
scrollTo(type, scrollId);
});
} else {
replaceBody(nextDoc);
runScripts();
scrollTo(type, scrollId);
}

// handle scroll
scrollToTop(type);

window.dispatchEvent(new CustomEvent('flamethrower:router:end'));

Expand Down

0 comments on commit 108f40f

Please sign in to comment.