Introduction
scrollnav.js is a small (2.4kb gzipped), dependency free JavaScript plugin
for auto generating single page navigation with active highlighting. Useful
for creating a Table of Contents for a large document (think Wikis),
navigation for a single page website, or anything else you might think of.
scrollnav works by scanning a block of content for section landmarks
(typically heading elements) and generating a list of links from those
landmarks. It then tracks the scroll location of the document and highlights
the appropriate link. While previous versions injected wrappers within the
content, the current version (ver 3) takes a much lighter approach, only
changing the DOM as necessary. Visit the live demo at scrollnav.com
to see for yourself.
Browser Compatibility
To keep scrollnav small, default support starts with
ES6 compatible browsers. To support
ES5 compatible browsers you must provide your
own polyfills or rely on a third party library like pollyfills.io. I personally
use the following
polyfill.io feature
parameters to support scrollnav in IE 10 & 11.
<script src="https://cdn.polyfill.io/v3/polyfill.min.js?features=default,NodeList.prototype.forEach,Array.prototype.includes"></script>
To add your own polyfills you will need to build the project from source.
Getting Started
The compiled, production ready plugin is available in the dist
directory.
Please don't use the src
directory unless you plan to build the entire
source.
Install
Download
scrollnav@v3.0.2
<script src="[your assets directory]/scrollnav.min.umd.js"></script>
CDN
<script src="https://unpkg.com/scrollnav@3.0.2/dist/scrollnav.min.umd.js"></script>
Package manager
Yarn: yarn add scrollnav
It's the new hotness, it's also better at managing dependencies than all it's predecesors.
NPM: npm install scrollnav
Good'ol NPM, it's always there, except when it isn't. Things have settled down a bit, but it was dicey there for a while. Even still, there's a reason even Yarn uses the NPM registry.
Bower: bower install scrollnav --save
The folks from Bower no longer recommend using Bower. Luckily they've provided a guide on how to migrate to Yarn. If you don't want to or can't migrate, scrollnav will continue to be available on Bower as long as it continues to run.
Usage
scrollnav works by scanning the given HTML Node Element for section
landmarks, by default h2
elements, that it then uses to generate the nav.
If we were to look at a typical document, it might look like this:
<div class="main-content">
<h2>First section</h2>
...
<h2>Second section</h2>
...
<h2>Third section</h2>
...
</div>
Initialize
First, initialize scrollnav with the HTML Element. In this example we'll use
.querySelector()
but you could also use .getElementByID()
or
.getElementByClassName()
.
const content = document.querySelector('.main-content');
scrollnav.init(content);
scrollnav will then loop through the the h2
elements, add an ID if they don't
already have one, build the nav, and then inject it just before the content
Node. The result for our example document would look like this:
<nav class="scroll-nav">
<ol class="scroll-nav__list">
<li class="scroll-nav__item">
<a class="scroll-nav__link" href="#scroll-nav__1">
First heading
<a>
</li>
...
</ol>
</nav>
<div class="main-content">
<h2 id="scroll-nav__1">First Heading</h2>
...
</div>
Styles
To keep the plugin simple there are no styles added to the navigation, that's
all up to you (view the demo site for exmaples of the most common use
cases). The nav structure provides BEM Methodology class names for each
of the elements to provide consistent styling hooks (for a good overview read
MindBEMding - getting your head 'round BEM syntax). As the user scrolls
the document, scrollnav adds a scroll-nav__item--active
modifier for the
item's relative section that currently intersects with the activation
threshold (enable debug
mode to highlight the
threshold).
Settings and options
scrollnav includes some default settings that work for most situations, but if
your project requires a bit more customization, scrollnav can most likely meet
those. To modify either, pass in a single object (include settings and options
as one object) as the second argument like this:
scrollnav.init(content, {
key: value
});
Default settings
The following settings are editable to overwrite the default.
{
sections: 'selector',
insertTarget: targetNode,
insertLocation: 'relativeLocation'
easingStyle: 'easingName',
updateHistory: true
}
Additional options
These additional options are editable but are not set by default.
{
subSections: '...',
onScroll: function() {...},
onInit: function() {...},
onUpdatePositions: function() {...},
onDestroy: function() {...},
debug: false
}
Available methods
In addition to the .init()
method scrollnav provides two additional public
methods.
destroy()
To remove the current instance of scrollnav call the destroy method. If you
need to trigger a callback after scrollnav has been removed, use the
onDestroy
option described above (passed either in the original init or with
the destroy method).
scrollnav.destroy();
updatePositions()
scrollnav doesn't track outside DOM changes. If your page's content is dynamic
and updates after scrollnav is initialized you'll need to recalcuate the
position data with the updatePositions method. If you need to trigger a
callback after the position data has been recalculated, use the
onUpdatePositions
option described above (passed either in the original init
or with the updatePositions method).
scrollnav.updatePositions();
Issues
Please read and understand the Contributing Guidelines prior to opening
an issue. Ensuring your issue conforms to the guidelines gives it a better
chance I'll be able to help address it.
Questions
For questions about using scrollnav in your own project, your best bet is to
post it to Stack Overflow. The community there is great at lending a hand
and can often respond faster than I can, plus it becomes searchable for future
developers who may run into the same question. If you're still stuck, please
feel free to reach out to me to ask for help or clarification, I'm @jimmynotim
on Twitter.
Changelog
v3.0.2 is the current stable release. For detailed changes in each release
please refer to the release notes. Please be sure you understand the
changes before updating, v3 is a complete re-write of the plugin (as is v2
compared to v1 before it).
Contributions
scrollnav is built and maintained by James Wilson (@jimmynotjim).
I wouldn't be able to continue this project without a lot of help from the
Open Source community. I welcome feedback and enhancements, but first, please
make sure to read the Contributing Guide.
Thank you to everyone who has already contributed to scrollnav!
License
scrollnav is Copyright © 2012-2018 James Wilson, released under the
MIT license. This means you can re-create, edit or share the plugin as
long as you maintain the same open licensing.