Automatically update your navigation components based on scroll position to indicate which link is currently active in the viewport.
npm i @three11/scrollspy
# or
yarn add @three11/scrollspy
or
Just download this repository and link the files located in dist folder:
<script src="path-to-scrollspy/dist/index.js"></script>
or
Include it from Unpkg CDN
<script src="//unpkg.com/@three11/scrollspy"></script>
First, import
the module:
import ScrollSpy from '@three11/scrollspy';
Then initialize a new instance of the module:
const scrollSpy = new ScrollSpy(scrollSpySettings, scrollSpyEasings);
The default settings are:
Name | Type | Description | Default |
---|---|---|---|
headerClass |
string |
The class name of your Header element | .c-header |
headerOffset |
boolean |
Flag which indicates if the Header height should be calculated | true |
animationSpeed |
number |
Speed of the scroll animation (in milliseconds) | 2000 |
animationEasing |
string |
Name of the easing function. For more details see below | easeInOutQuint |
sectionSelector |
string |
CSS selector for your Section elements | .js-scroll-spy-section |
linkCurrentClass |
string |
Class name to be applied to the currently active link | current |
linksContainerSelector |
string |
CSS selector for your scroll spy navigation | .js-scroll-spy-nav |
onAfterScroll |
function |
A function to run after the scroll after click on a link is complete | () => {} |
The ScrollSpy
instance accepts a second optional argument which specifies a list of easing functions.
The current list contains several predefined easing functions:
{
linear: t => t,
easeInQuad: t => t * t,
easeOutQuad: t => t * (2 - t),
easeInCubic: t => t * t * t,
easeOutCubic: t => --t * t * t + 1,
easeInQuart: t => t * t * t * t,
easeOutQuart: t => 1 - --t * t * t * t,
easeInQuint: t => t * t * t * t * t,
easeOutQuint: t => 1 + --t * t * t * t * t,
easeInOutQuad: t => (t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t),
easeInOutCubic: t => (t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1),
easeInOutQuart: t => (t < 0.5 ? 8 * t * t * t * t : 1 - 8 * --t * t * t * t),
easeInOutQuint: t => (t < 0.5 ? 16 * t * t * t * t * t : 1 + 16 * --t * t * t * t * t),
}
If you wish to add your own easing function, you can do so by adding it to the second argument of the ScrollSpy
constructor.
Just remember that your custom easing function should accept a single time
argument which is a number
and should return a number
.
In order to use your custom easing function, you need to specify its name in the animationEasing
setting.
There are two public methods of the ScrollSpy
instance.
The unbind
method unbinds (removes) all of the event listeners and the bind
method binds (adds) all of the event listeners.
These methods are useful in various cases - for example if you load the content of your pages with AJAX and you want to remove all possible memory leaks after you remove the ScrollSpy markup/HTML.
Here is how you can use them:
const scrollSpy = new ScrollSpy(scrollSpySettings, scrollSpyEasings);
// Later in your code
scrollSpy.unbind();
// Then, if you wish to re-enable the ScrollSpy functionality
scrollSpy.bind();
new ScrollSpy(
{
linkCurrentClass: 'current',
linksContainerSelector: '.nav',
sectionSelector: '.section',
headerOffset: true,
headerClass: '.header',
animationSpeed: 3000,
animationEasing: 'customEasingFunction',
onAfterScroll: () => {
console.log('scroll ended');
}
},
{
customEasingFunction: t => t ** t
}
);
A minimal demo is available here
GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007