I’m working on another site, written directly in HTML and stitched together with
the C preprocessor (it’s really quite ergonomic!) and using the excellent Python
package reloadserver to automatically reload the pages in my
browser whenever I make changes.
Unfortunately, Firefox, at least, doesn’t remember
and restore scroll position on reload, which may be the behavior one wants when
actually browsing, but is really annoying during the writing and design process.
Fortunately, the JS browser APIs provide very simple interfaces to the page’s
scroll position in window.scrollY and window.scroll(x, y).
scrollY is a subpixel-precise measurement of where the user has scrolled, and
scroll() takes integer arguments for horizontal and vertical coordinates to
which to scroll. All we need to do is save the (rounded) value from the first
whenever the user scrolls and feed it into the second when the user reloads the
page.
We don’t want to use a cookie or localStorage, because those methods
of data storage persist between browser sessions and across browser tabs.
Instead, we want to use sessionStorage, a very simple KV
store whose values are wiped away when the tab or window is closed.
The document API also provides a way to run code on many different events,
including scrolling the page, via addEventListener.
The document’s 'scroll' event fires whenever the user
scrolls, so that’s what we’ll attach to.
Combining these APIs in a short JavaScript snippet, as follows, at the bottom of my web page resulted in exactly the behavior I was looking for.
<script language="javascript">
document.addEventListener('scroll', (_evt) => {
const scrollPositionY = Math.round(window.scrollY);
window.sessionStorage.setItem('scroll_position_y', scrollPositionY);
});
const y = sessionStorage.getItem('scroll_position_y') || 0;
window.scroll(0, y);
</script>
'scroll_position_y', here, is an arbitrarily chosen key for the session
storage KV store. It could be whatever you like. If you want to store horizontal
position too, add another key, like 'scroll_position_x', storing that value.
Now, the script added by reloadserver reloads the page, which runs my script,
which reads the previous scroll position out of session storage and teleports me
right back where I was; the delay is imperceptible.
Cheers, and if you have improvements to suggest or find issues with this approach, let me know!