Angular Waypoints is an AngularJS module for working with jQuery Waypoints.
Waypoints is a jQuery plugin that makes it easy to execute a function whenever you scroll to an element.
// example from http://imakewebthings.com/jquery-waypoints/
$('.thing').waypoint(function(direction) {
alert('Top of thing hit top of viewport.');
});
The above example from the jQuery waypoints homepage works well for most situations. However, if you were to put the above code inside an AngularJS directive, you end up with a couple of drawbacks:
- The waypoints implementation is hidden from the HTML. All you know is that a directive is doing something, but you do not know the contents of the callback function.
- If you modify a scope property in your callback, you'll need to manually call
$scope.$digest
to let angular process this new information.
With Angular Waypoints, your template becomes declarative. For example, you could toggle between two CSS classes (sticky
and notSticky
) by attatching a waypoint and using ngClass
to listen to the waypoint flags:
<div zum-waypoint="waypoints"
down="flags.on"
up="flags.off"></div>
<div ng-class="{
sticky : waypoints.flags.on,
notSticky : waypoints.flags.off
}"></div>
Angular Waypoints works by taking the control of the waypoints callback away from the developer. When a waypoint is triggered by scrolling the page, the directive executes an internal callback that toggles a boolean flag based on the direction of the scroll. These flags can be used by other directives (like ngClass
or ngIf
) to modify application state.
Install Angular Waypoints via bower:
$ bower install angular-waypoints
Angular Waypoints comes with several packaged versions:
dist/angular-waypoints.js
Development — AMD compatable, commented.dist/angular-waypoints.min.js
Production — Minified, stripped of comments.dist/angular-waypoints.all.js
Standalone — Same as the Development version, but includes unminified versions of lodash and jQuery Waypoints.dist/angular-waypoints.all.min.js
Standalone Compressed — Same as the Standalone version, but minified.dist/angular-waypoints.raw.js
Raw — This is a simple version that isn't very useful by itsself. There is nozumba.angular-waypoints
module. The directive, controller, and service functions are all exposed to the global scope. Use this if you want to package our code into another library, register individual components yourself, or do something custom.
angular.module('YourModule', ['zumba.angular-waypoints']);
Attach the zum-waypoint
directive to each element for which you want to trigger a waypoint flag. Each waypoint can be configured to use one flag for scrolling up, one flag for scrolling down, and an offset value if needed. See the jQuery Waypoints Documentation for an explanation of offset.
up
, down
, and offset
are HTML attributes that are bound to the isolated scope of the directive. Here is a full example of a template:
<div zum-waypoint="waypoints"
down="name.down"
up="name.up"
offset="20%"></div>
- The
waypoints
property of the parent scope will be used to hold the flags triggered by the directive. This is indicated by the expression passed to the bltWaypoint directive. It should be a plain old javascript object{}
. - When the element is 20% away from the top of the viewport while scrolling down,
waypoints.name.down
will be set totrue
, andwaypoints.name.up
will be set to false. - If the direction was scrolling up,
waypoints.name.down
will be set tofalse
, andwaypoints.name.up
will be set to true.
Notice that the examples have included a "namespace" for the flags (in the first exmaple flags.up
has the flags
namespace). This allows you to use several groups of waypoints on the same view. When toggling a waypoint flag to true
, all other flags that share the same namespace will be toggled to false
. Flags that exist in another namespace are left unchanged.
If you do not use a namespace, the directive will store the flags inside a namespace called globals
:
<div zum-waypoint="waypoints"
down="someFlag"
up="anotherFlag"></div>
The above flags would be accessed via waypoints.globals.someFlag
and waypoints.globals.anotherFlag