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

naviscroll

v1.1.2

Published

A small package to create a navigation component from sections of a website and track which one is in view

Readme

naviscroll.js

Naviscroll.js is a lightweight customizable library for generating a navigation menu from the sections on your website and keeping track which one is in view.

It parses the container you give it for elements with observe-section class by default, gets their headings (see options section), sets section ids, initializes the Intersection Observer for each one to keep track which one is in view now, and goes finding any nested sections repeating same thing for them.

You can hook into the navigation build process with onSectionBuild and add extra actions to do as well as set a custom function to execute on section getting in or out of view with onSectionIn and onSectionOut to enrich it with fancy animations, for example.

Check out a live demo

Installation

Use npm to install and use with a module bundler.

npm install naviscroll

Also you can use a CDN.

<script src="https://unpkg.com/[email protected]/naviscroll.umd.js"></script>

Or download the zip and put it into your project folder, then include directly into HTML.

<script src="naviscroll.umd.js"></script>

Usage

Using a module bundler

import naviscroll from 'naviscroll'
// target can be either a string for query selector ('.sections')
// or a document element (document.querySelector('.sections'))

naviscroll(target, {
  key: value,
});

Using a CDN or including directly into HTML Naviscroll exposes the naviscroll function to window object

naviscroll(target, {
  key: value,
});

Options

Here are the default options you are free to override within options passed to naviscroll:

// DEFAULTS
const defaultProps = {
  // Set to false to prevent recursive generation of sections
  subsections: true,

  // Set to false not to create links for sections
  createLinks: true,

  // Set to false to disable setting ids for sections
  setSectionIds: true,

  // Element to append to or a selector.
  appendTo: '',

  // Selector for document sections to observe generate navigation from
  sectionsClass: '.observe-section',

  // Selector for document section-heading to generate the names of nav sections
  // You can also set headings via data-heading attribute on the section itself
  sectionHeadingClass: '.observe-section__heading',

  // Set to false to disable building navigation to use only sections observer
  buildNav: true,

  // Function to execute on section build to add extra classes or properties.
  onSectionBuild: ({
    sectionEl,
    navSectionEl,
    parent,
    depth,
  }) => {},

  // Tag to use for nav element
  navTag: 'nav',

  // Classname to give to navigation element
  navClass: 'naviscroll',
  
  // Classname for navigation section
  navSectionClass: 'naviscroll__section',
  
  // Classname for navigation sub-sections container
  navSubSectionClass: 'naviscroll__sub-section',
  
  // Type of list to use in navigation
  navListType: 'ul',

  // Type of element to create for navigation section
  navSectionTag: 'li',

  // String to insert before id number;
  idString: '',

  // String to separate sections and subsections ids
  idSeparator: '-',

  // Set to false to disable observing sections
  observe: true,

  // Function to call when section gets into view
  onSectionIn: ({
    sectionEl, navEl, id, depth,
  }) => {
    // do stuff with elements here
  },

  // Function to call when section gets out of view
  onSectionOut: ({
    sectionEl, navEl, id, depth,
  }) => {
    // do stuff with elements here
  },

  // Root margin for intersection observer
  rootMargin: '-50% 0px -50% 0px',

  // Root element for intersection observer, viewport by default
  observerRoot: null,

};

You can style navigation elements using data-depth indicating how deep the element is in sections.

Note that you can use data-heading attribute on the section to set the heading you want in the navigation.

Browser support

ES6 compatible browsers are supported out of the box, but if you need IE support you might want to use polyfills for object destructuring, js Classes, NodeList.prototype.ForEach, Element.classList or just put it through Babel.

The library uses :scope selector and Intersection Observer API which are not well-supported in older browsers, so if you need to support those, please use the polyfills for: