AnchorTrigger
AnchorTrigger is a lightweight JavaScript library to trigger a callback whenever the user scrolls past an anchor. A simple use-case is to change active navigation when scrolling a new section into view.
Its designed to be effecient, for example, callbacks are throttled to 50ms rather than continuous (you can change this).
The library doesn't have any dependencies and is just 1K when gzipped. The source should be pretty straight forward and easy to update. It is written in plain old ES5.
Example
See the example discussed below.
Usage
A simple use case. Suppose you have a simple navigation menu, such as:
<ul class="nav">
<li><a href="#one">One</a></li>
<li><a href="#two">Two</a></li>
<li><a href="#three">Three</a></li>
</ul>
You have in page anchor like so:
<a name="two"></a>
<div>Lorem ipsum...</div>
Now you want to have the current navigation item's class set to "selected". This is how you could use this library to solve this problem
var ezQuery = function( query, context ){
var context = context || document;
var result = context.querySelectorAll( query );
return Array.prototype.slice.call( result );
};
var pathToItem = '.nav li';
var anchors = ezQuery( pathToItem + ' a' ).map( function( anchor ){ return anchor.href.split( '#' ).slice(-1) } )
var callback = function(obj){
var query = 'a[href="#'+obj.name+'"]';
var navItem = document.querySelector( query );
// callback is called only on a trigger change (onlyOnChange: true). Default behavior.
ezQuery( pathToItem ).map( function( li ){ li.classList.remove( 'selected' ) })
navItem.parentElement.classList.add('selected')
}
var aTrigger = new AnchorTrigger(anchors,callback);
That's it! :-)
API
var trigger = AnchorTriggre( listOfAnchorNames, callback, { query: 'a', ... } )
Where
Parameter | Type | Required |
---|---|---|
listOfAnchorNames | ARRAY | YES |
callback | FUNCTION | YES |
options | OBJECT | NO |
Callback receives a single parameter of type OBJECT
which describes the anchor being triggered as follows
{
name: DOMelement.name,
element: DOMelement,
cumlativePosition: {
top: 0, // INTEGER, distance DOMelement is in pixes from the top of the screen (or element see below).
left: 0, // INTEGER, distance DOMelement is in pixels from left side of screen (or element see below).
},
scrollPosition: {
top: 0, // INTEGER, relative distance of scroll position from top of screen
left: 0, // INTEGER, relative distance of scroll position from left of screen
}
Additionally, option
can be used to fine-tune behavior as needed. This takes an object as follows:
listOfAnchorNames // ARRAY || array containing the names of anchors to watch
callback // FUNCTION || function to callback when within a certain anchor
// options is an obj with the following properties, default value given.
{
query: 'a', // STRING || tags to query as anchors.
// Could give class, ie. a.foobar would search a tags
// with class foobar
onlyOnChange: true // BOOLEAN || Only call callback when anchor has changed.
fraction: .5, // FLOAT || fraction of page (top to bottom or left to right)
// to trigger new area.
delay: 50, // INTEGER || Delay to throttle calls during scroll
bind: window, // OBJ || The element we are watching for scroll.
// Pass the element itself, not a string.
flow: 'top', // STRING || Direction of scroll flow. Options are
// 'top' -- as in top to bottom
// 'left' -- as in left to right
alwaysCallback: undefined // FUNCTION || This is a callback that is always
// called even when trigger remains the same.
}
Here is a table description of the input values
Key | Value Type | Default | Description |
---|---|---|---|
query | STRING | 'a' | Describes the query for anchors, can be changed to include classes, etc. |
onlyOnChange | BOOLEAN | true | If true, callback is only called if there is a new trigger. |
fraction | FLOAT | .5 | How far off the screen the current element has to be to trigger the incoming anchor |
delay | INTEGER | 50 | Maximum rate by whic the any callback function is called, including alwaysCallback below |
bind | DOM | window | The DOMelement scrolling is binding to. Untested for other than window. |
flow | STRING | 'top' | If the page is flowing top-to-bottom or left-to-right. Only tested for top-to-bottom. |
alwaysCallback | FUNCTION | undefined | A function that is always acalled back even if there isn't a trigger change |