-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathindex.js
130 lines (113 loc) · 3.45 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
var Emitter = require('emitter');
var each = require('each');
var bind = require('bind');
var offset = require('offset');
var classes = require('classes');
var throttle = require('throttle');
var events = require('event');
/**
* Waypoints object takes points on the page and binds a scroll event
* to the window. When these points are reached it will add or remove
* a class from the element
*/
function Waypoints() {
this.points = [];
this._onScroll = throttle(bind(this, this._onScroll), 200);
}
/**
* Mixin an event emitter so we can emit and bind to events
*/
Emitter(Waypoints.prototype);
/**
* Add a waypoint.
* @param {Number} point
* @param {Object} data Any data associated with this point
*/
Waypoints.prototype.addPoint = function(point, data) {
this.points.push({ y: point, data: data });
};
/**
* Start the waypoints. Binds events to the window so they waypoints
* will trigger when they are reached
*/
Waypoints.prototype.start = function() {
events.bind(window, 'scroll', this._onScroll);
this._onScroll();
this.emit('start');
};
/**
* Method that is fired when scrolling. Checks to see if any of
* the points is matched and if it is it will add or remove a class
* from the elment
*/
Waypoints.prototype._onScroll = function() {
var scrollPoint = window.scrollY || window.pageYOffset;
var wHeight = window.innerHeight;
var self = this;
var newPoints = [];
this.each(function(point){
if( (scrollPoint + wHeight) >= point.y ) {
self.fire(point);
}
else {
newPoints.push(point);
}
});
this.points = newPoints;
};
/**
* Disable the waypoints by removing the scroll events
*/
Waypoints.prototype.stop = function() {
events.unbind(window, 'scroll', this._onScroll);
this.emit('stop');
};
Waypoints.prototype.each = function(callback) {
each(this.points, callback.bind(this));
};
Waypoints.prototype.fire = function(point) {
this.emit('point', point.y, point.data);
return this;
};
Waypoints.prototype.remove = function(point) {
this.points = this.points.filter(function(pointB){
return pointB !== point;
});
return this;
};
/**
* Easy way to setup waypoints on a page. Takes a selector
* to match points on the page. Then we can use a data-API
* to create waypoints on the page.
* @param {String} selector CSS selector to match elements on the page which will be used as Waypoints
* @return {Waypoints}
*/
Waypoints.create = function(options) {
options = options || {};
var selector = options.selector || '.js-waypoint';
var addClass = options.addClass || null;
var removeClass = options.removeClass || null;
var delay = options.delay || 0;
var pointOffset = options.offset || 0;
var waypoints = new Waypoints();
var matched = document.querySelectorAll(selector);
each(matched, function(el){
var y = offset(el).top + Number(el.getAttribute('data-waypoint-offset') || pointOffset);
waypoints.addPoint(y, {
el: el,
addClass: el.getAttribute('data-waypoint-addClass') || addClass,
removeClass: el.getAttribute('data-waypoint-removeClass') || removeClass,
delay: Number(el.getAttribute('data-waypoint-delay')) || delay
});
});
waypoints.on('point', function(point, data){
setTimeout(function(){
var classList = classes(data.el);
if(data.addClass) classList.add(data.addClass);
if(data.removeClass) classList.remove(data.removeClass);
}, data.delay);
});
waypoints.start();
return waypoints;
};
module.exports = Waypoints;