📜 A super-tiny library for your scrollytelling needs.
@newswire/scrolleris a super-tiny library for your scrollytelling needs.
@newswire/scrolleris available via
npm.
npm install @newswire/scroller
You can also use it directly via unpkg.com.
You can also import it as a module via unpkg!
Assume for the following examples that our HTML is as follows:
To begin tracking the progression of the scenes, we need to set up our
Scroller.
import Scroller from '@newswire/scroller';// sets up the scroller instance, pass in an array of all the scenes const scroller = new Scroller({ scenes: document.querySelectorAll('.scene'), });
// Scroller has a tiny event emitter embedded in it!
// the
enter
event is triggered every time a scene crosses the threshold scroller.on('scene:enter', d => { d.element.classList.add('active'); });// the
exit
event is triggered every time a scene exits the threshold scroller.on('scene:exit', d => { d.element.classList.remove('active'); });scroller.on('init', () => { console.log('Everything is ready to go!'); });
// starts up the IntersectionObserver scroller.init();
If you need to additionally track the "container" of your scenes,
Scrollercan track and alert you about that too.
import Scroller from '@newswire/scroller';// sets up the scroller instance, pass in the container and an array of all the scenes const scroller = new Scroller({ container: document.querySelector('.container'), scenes: document.querySelectorAll('.scene'), });
// the
enter
event works as you expect with scenes... scroller.on('scene:enter', d => { d.element.classList.add('active'); });scroller.on('scene:exit', d => { d.element.classList.remove('active'); });
// ...but if a container is passed, events fire for it as well! scroller.on('container:enter', d => { console.log("Let's go!"); });
scroller.on('container:exit', d => { console.log('We are done here.'); });
scroller.init();
This is a minor quirk of Intersection Observer to keep in mind. Whenever an element gets added to an Intersection Observer instance it is immediately checked for intersection. In the context of
Scroller, this means that if it is instantiated on load of a page and none of its elements are currently intersecting,
scene:exit(and possibly
container:exit) is going to fire for each element as they fail that initial check. The good thing is this is also true for the
*:enterevents, so nothing special is necessary for detecting if someone loads in the middle of your interactive. Make sure the code in your event listeners are prepared for this and have some way to determine whether anything in your
*:exitlisteners are needed yet!
To keep the library lean,
@newswire/scrollerintentionally does not attempt to polyfill
IntersectionObserverand leaves that task up to the user if necessary. Browser support is pretty good! There's no hard and fast rule here - check what browsers your users are using and make a call.
There are a few good ways to ensure the polyfill is in place.
The spec-based Intersection Observer polyfill is available on
npm.
npm install intersection-observer
Once that is installed, you need to make sure that it is loaded before any code that'd depends on it will run. The polyfill is smart - it won't affect browsers who already have support!
import 'intersection-observer'; // or require('intersection-observer');// your awesome code here!
polyfill.io
Before loading your scripts, you can include a link to
polyfill.io. This service uses signals from the browser to determine what polyfills are needed and loads them in the environment. You can set flags on the URL to limit what
polyfill.ioattempts to load.
unpkg.com
This is similar to the
polyfill.iomethod, but without a service in-between determining whether it is necessary.
Uses Intersection Observer to monitor the page location of a series of elements for scrollytelling.
optionsobject
options.containerElement? Optionally pass in what should be considered the containing element of all the scenes - this gets added to the Intersection Observer instance and additionally fires its own events
options.offsetNumber? How far from the top/bottom of the viewable area to trigger enters/exits of scenes, represented as a value between 0 and 1 (optional, default
0.5)
options.scenesArray<Element> An array of all the Elements to be considered scenes of this Scroller
observer(IntersectionObserver | null) Once initialized, a reference to the Scroller's instance of IntersectionObserver
import Scroller from '@newswire/scroller';const scroller = new Scroller({ scenes: document.querySelectorAll('.scenes'), });
scroller.init();
Adds a callback to the queue of a given event listener.
const scroller = new Scroller({ scenes: document.querySelectorAll('.scenes') });const fn = (...) => {...};
// adds callback to listener scroller.on('scene:enter', fn);
Returns void
Removes a callback from the queue of a given event listener.
const scroller = new Scroller({ scenes: document.querySelectorAll('.scenes') });const fn = (...) => {...};
// adds callback to listener scroller.on('scene:enter', fn);
// removes callback from listener scroller.off('scene:enter', fn);
Returns void
Initializes a Scroller's IntersectionObserver on a page and begins sending any intersection events that occur.
const scroller = new Scroller({ scenes: document.querySelectorAll('.scenes'), });scroller.init();
Returns void
Container enter event. Fires whenever the container begins intersecting.
Type: object
boundsDOMRectReadOnly The bounds of the active element
elementElement The element that intersected
indexnumber This is always -1 on the container
isScrollingDownboolean Whether the user triggered this element while scrolling down or not
Scene enter event. Fires whenever a scene begins intersecting.
Type: object
boundsDOMRectReadOnly The bounds of the active element
elementElement The element that intersected
indexnumber The index of the active element
isScrollingDownboolean Whether the user triggered this element while scrolling down or not
Container exit event. Fires whenever the container has exited.
Type: object
boundsDOMRectReadOnly The bounds of the exiting element
elementElement The element that exited
indexnumber This is always -1 on the container
isScrollingDownboolean Whether the user triggering the exit while scrolling down or not
Scene enter event. Fires whenever a scene has exited.
Type: object
boundsDOMRectReadOnly The bounds of the exiting element
elementElement The element that exited
indexnumber The index of the exiting element
isScrollingDownboolean Whether the user triggering the exit while scrolling down or not
Init event. Fires once Scroller has finished setting up.
MIT