npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

scrollmus

v6.0.1

Published

Framework-agnostic scrollspy script, fork of Gumshoe.

Readme

Scrollmus

Framework-agnostic scrollspy script, fork of Gumshoe by cferdinandi. The latest compiled release can be found in the dist directory.

What's different?

  • Added useLast toggle, resolving GS#128.
  • Merged GS#111.
  • Merged GS#117.
  • Removed polyfill support (Internet Explorer).

Browser Support

Scrollmus supports all modern browsers; this does not include Internet Explorer.

| Firefox | Chrome | Edge | Safari | IE | | :---: | :---: | :---: | :---: | :---: | | 35+ | 41+ | 15+ | 9+ | -- |

Include

Static

Download the latest compiled release from the dist directory. Include the minified script in the footer of required pages.

<script defer src="/path/to/scrollmus.min.js"></script>

Hugo

Scrollmus can be loaded as a Hugo Module.

Initialize the Hugo project as a Hugo Module. Replace the path with your repository.

hugo mod init codeberg.org/username/project

Add the following [module] configuration to the project's config.toml file. If the codeberg.org import fails for your project, replace it with gitlab.com or github.com. Scrollmus is mirrored with each commit.

[module]
  [[module.imports]]
    path = 'codeberg.org/aao-fyi/scrollmus'
  [[module.imports.mounts]]
    source = 'dist/'
    target = 'assets/js/scrollmus/'

Load Scrollmus wherever necessary.

{{ $scrollmus := resources.Get "js/scrollmus/scrollmus.min.js" }}
<script defer src="{{ $scrollmus.RelPermalink }}"></script>

Optionally use subresource integrity.

{{ $scrollmus := resources.Get "js/scrollmus/scrollmus.min.js" }}
{{ $scrollmusSRI := $scrollmus | resources.Fingerprint "sha384" }}
<script defer src="{{ $scrollmusSRI.RelPermalink }}" integrity="{{ $scrollmusSRI.Data.Integrity }}"></script>

NPM

The wombats of the group can use NPM.

npm install scrollmus

Usage

The only thing Scrollmus needs to work is a list of anchor links. They can be ordered or unordered, inline or unstyled, or even nested.

<ul id="my-awesome-nav">
	<li><a href="#eenie">Eenie</a></li>
	<li><a href="#meenie">Meenie</a></li>
	<li><a href="#miney">Miney</a></li>
	<li><a href="#mo">Mo</a></li>
</ul>

In the footer of your page, after the include, initialize Scrollmus by passing in a selector for the navigation links that should be detected as the user scrolls.

<script>
	var spy = new Scrollmus('#my-awesome-nav a');
</script>

Styling

Scrollmus adds the .active class to the list item (<li></li>) and content for the active link, but does not include any styling. Add styles to your CSS as desired to control the appearance.

Class names can be customized with user options.

#my-awesome-nav li.active a {
	font-weight: bold;
}

API

Scrollmus includes smart defaults and works right out of the box. There is also an API that provides multiple ways to adjust the default options and settings.

Options and Settings

You can pass options into Scrollmus during initialization.

var spy = new Scrollmus('#my-awesome-nav a', {

	// Active classes
	navClass: 'active', // applied to the nav list item
	contentClass: 'active', // applied to the content

	// Nested navigation
	nested: false, // if true, add classes to parents of active link
	nestedClass: 'active', // applied to the parent items

	// Offset & reflow
	offset: 0, // how far from the top of the page to activate a content area
	reflow: false, // if true, listen for reflows

	// Event support
	events: true, // if true, emit custom events

	// End of page
	useLast: true // if true, the last page item will be set as 'active' when scrolled to bottom
});

Custom Events

Scrollmus emits two custom events:

  • scrollmusActivate is emitted when a link is activated.
  • scrollmusDeactivate is emitted when a link is deactivated.

Both events are emitted on the list item and bubble up. You can listen for them with the addEventListener() method. The event.detail object includes the link and content elements, and the settings.

// Listen for activate events
document.addEventListener('scrollmusActivate', function (event) {

	// The list item
	var li = event.target;

	// The link
	var link = event.detail.link;

	// The content
	var content = event.detail.content;

}, false);

Methods

Scrollmus exposes three public methods.

setup()

Setups all of the calculations Scrollmus needs behind-the-scenes. If you dynamically add navigation items to the DOM after Scrollmus is started, you can run this method to update the calculations.

var spy = new Scrollmus('#my-awesome-nav a');
spy.setup();

detect()

Activate the navigation link that's content is currently in the viewport.

var spy = new Scrollmus('#my-awesome-nav a');
spy.detect();

destroy()

Destroy the current Scrollmus instance.

var spy = new Scrollmus('#my-awesome-nav a');
spy.destroy();

Examples

Nested Navigation

If you have a nested navigation menu with multiple levels, Scrollmus can also apply an .active class to the parent list items of the currently active link.

<ul id="my-awesome-nav">
	<li><a href="#eenie">Eenie</a></li>
	<li>
		<a href="#meenie">Meenie</a>
		<ul>
			<li><a href="#hickory">Hickory</a></li>
			<li><a href="#dickory">Dickory</a></li>
			<li><a href="#doc">Doc</a></li>
		</ul>
	</li>
	<li><a href="#miney">Miney</a></li>
	<li><a href="#mo">Mo</a></li>
</ul>

Set nested to true to use nesting. Class names can be customized with user options.

var spy = new Scrollmus('#my-awesome-nav a', {
	nested: true,
	nestedClass: 'active-parent'
});

Catching Reflows

If the content that's linked to by your navigation has different layouts at different viewports, Scrollmus will need to detect these changes and update some calculations behind-the-scenes.

Set reflow to true to enable this (it's off by default).

var spy = new Scrollmus('#my-awesome-nav a', {
	reflow: true
});

Fixed Headers

If you have a fixed header on your page, you may want to offset when a piece of content is considered "active."

The offset user setting accepts either a number, or a function that returns a number. If you need to dynamically calculate dimensions, a function is the preferred method.

Here's an example that automatically calculates a header's height and offsets by that amount.

// Get the header
var header = document.querySelector('#my-header');

// Initialize Scrollmus
var spy = new Scrollmus('#my-awesome-nav a', {
	offset: function () {
		return header.getBoundingClientRect().height;
	}
});

Use Last Item

By default, when the user scrolls to the bottom of the page the last item will be marked active. To prevent this behavior, set useLast to false when you call Scrollmus. When useLast is false, the item at the top of the page will continue to be marked active.

var spy = new Scrollmus('#my-awesome-nav a', {
	useLast: false
});

Issues

Open new issues in the Codeberg Issue Tracker.

License

Scrollmus is distributed under the MIT License.