@hirasso/restore-scroll
TypeScript icon, indicating that this package has built-in type declarations

0.1.6 • Public • Published

@hirasso/restore-scroll

e2e test status unit test status license

Vanilla JavaScript scroll restoration for overflowing elements and the window using history.state ♻️

Demo

restore-scroll.js.org

Installation

Install and import into your bundle

npm i @hirasso/restore-scroll
import { restoreScroll } from "@hirasso/restore-scroll";

Or import the module directly from a CDN for quick tests:

<script type="module">
  import { restoreScroll } from "https://unpkg.com/@hirasso/restore-scroll@0";
</script>

Usage

/**
 * 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:

window.history.scrollRestoration = "manual";
restoreScroll(window);

Arguments

The first argument target accepts either an element or the Window:

export type Target = Element | Window;

The second argument options accepts this:

type Options = {
  debug?: boolean;
  events?: {
    store?: (el: Element, event: CustomEvent<position: ScrollPosition>) => void,
    restore?: (el: Element, event: CustomEvent<position: ScrollPosition>) => void,
  }
}

Options

debug

Type: boolean, default: false. Log debug info to the console

Events

Listening to events can be done in two ways:

Option 1: Attach listeners declaratively

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),
  },
});

Option 2: Attach listeners to the element directly

DOM events are prefixed with restore-scroll::

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:

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.

Readme

Keywords

none

Package Sidebar

Install

npm i @hirasso/restore-scroll

Weekly Downloads

4

Version

0.1.6

License

MIT

Unpacked Size

49 kB

Total Files

14

Last publish

Collaborators

  • hirasso