@spa-tools/core-router
Hash Autoscroll
Using URL hashes to scroll to content has been around a long time, but this native functionality can get ugly and convoluted when implemented in a SPA, especially when you're trying to scroll to a specific element right after a view loads.
While the @spa-tools/core-router
typically stays out of the UI rendering/interaction
business, this is one scenario it dives head first into to enable simple auto-scroll
to html elements via its navigation feature.
import { CoreRouter, routesFactory } from '@spa-tools/core-router';
const createMyRoutes = routesFactory();
// here we create two routes where we will "pretend" that the About
// route has a "Careers" section that we want to auto-scroll to
const myRoutes = createMyRoutes({
homeRoute: {
path: '/',
},
aboutRoute: {
path: '/about',
// here we specify that for this route we'd like any auto-scrolling
// via hash navigation to be smooth; we could omit this and the
// behavior would default to 'auto' or we could also set it to 'instant'
hashScrollBehavior: 'smooth',
},
});
// here we create a new instance of the CoreRouter class and pass in
// our routes object; we also pass in an object that implements the
// router lifecycle callback onRouteChange so we can log outcomes
const myRouter = CoreRouter.initialize(myRoutes, {
onRouteChange: (routeChange) => {
// this is where we would perform any post-processing logic, which
// typically means rendering the requested route. How to do this
// ranges based on the UI framework being used, so here we simply
// log path info to the console.
//
// If you're using React or want to create an abstraction for a
// different rendering package/framework, you should definitely
// check out the Core React Router abstraction, which has the
// rendering logic sweetly baked in.
console.log(
`Route change with hash in path: ${window.location.pathname + window.location.search + window.location.hash}`
);
},
});
// first, we navigate to the home route
myRouter.navigate(myRoutes.homeRoute);
// next, we navigate to the about route and specify a hash so the
// browser will auto-scroll to the Careers section, if it exists.
// And by exists, we mean that the rendered content must have a
// DOM element with the ID of "careers".
//
// And that's it. Easy-peasy. Pretty cool, huh?!?!
myRouter.navigate(myRoutes.aboutRoute, undefined, 'careers');