Vanilla JavaScript scroll restoration for overflowing elements and the window using `history.state` ♻️
npm install @hirasso/restore-scroll
history.state ♻️
bash
npm i @hirasso/restore-scroll
`
`js
import { restoreScroll } from "@hirasso/restore-scroll";
`
Or import the module directly from a CDN for quick tests:
`html
`
Usage
`js
/**
* Track and restore the scroll positions of all overflowing divs,
* identified by tailwind classes in this case:
*/
document
.querySelectorAll(".overflow-y-auto,.overflow-x-auto,.overflow-auto")
.forEach((el) => restoreScroll(el));
`
💡 If history.scrollRestoration is set to manual, you might want to restore the window scroll position as well:
`js
window.history.scrollRestoration = "manual";
restoreScroll(window);
`
Arguments
The first argument target accepts either an element or the Window:
`ts
export type Target = Element | Window;
`
The second argument options accepts this:
`ts
type Options = {
debug?: boolean;
events?: {
store?: (el: Element, event: CustomEvent) => void,
restore?: (el: Element, event: CustomEvent) => void,
}
}
`
Options
$3
Type: boolean, default: false. Log debug info to the console
Events
Listening to events can be done in two ways:
$3
`ts
import { restoreScroll } from "@hirasso/restore-scroll";
restoreScroll(el, {
events: {
store: (el, event) => console.log("stored", el, event),
restore: (el, event) => console.log("restored", el, event),
},
});
`
$3
DOM events are prefixed with restore-scroll::
`ts
import { restoreScroll } from "@hirasso/restore-scroll";
const el = document.querySelector("#foo");
el.addEventListener("restore-scroll:restore", (e) => {
const event = e as CustomEvent<{ position: ScrollPosition }>;
/* The position is available in event.detail.position /
console.log(event.detail.position);
});
restoreScroll(el);
`
event.preventDefault works as expected:
`ts
restoreScroll(el, {
events: {
restore: (el, event) => {
if (someCondition()) {
/* The element won't be restored /
event.preventDefault();
}
},
},
});
`
Motivation
There already are other solutions for storing and restoring the scroll position. But all I could find was either archived by their owner, had a dependency (React in most cases) or was using sessionStorage for storing the scroll positions, which is not ideal (with sessionStorage`, one URL can only store one scroll state, ever). Hence, this new little package.