-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathjquery.scrolled.js
78 lines (70 loc) · 2.4 KB
/
jquery.scrolled.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
(function($){
var event_interval = 60 // max frequency of global scroll events
, scroll_top = -1 // persistant reference to the distance scrolled
, window_height = 0 // global reference to window height
, scroll_callbacks = [] // all of the callbacks to be called on scroll events
;
// normalize the body/html scrollTop() call
function scrollTop() {
var top = $('body').scrollTop();
if (top == 0) { return $('html').scrollTop(); }
else { return top; }
}
// recalculate globals and return whether a scroll happened
function scrollTick() {
var new_scroll = scrollTop();
if (new_scroll !== scroll_top) {
// recalculate window height on each frame
window_height = $(window).height();
scroll_top = new_scroll;
return true;
}
return false;
}
// Shift an argument of a certain type off the array if available
function shifted(args, kind) {
return (args.length && typeof args[0] == kind) ? args.shift() : false;
}
//
// The jQuery scrolled plugin - three API's are provided:
//
// $(window).on('scrolled', function(event, position){...})
// $('#my-div').scrolled('body-class-to-toggle')
// $('#my-div').scrolled(function in(){...}, function out(){...})
//
$.fn.scrolled = function(){
var args = Array.prototype.slice.call(arguments)
, $ref = this
, class_name = shifted(args, 'string')
, cb = shifted(args, 'function')
, second_cb = shifted(args, 'function')
, class_toggled = false
;
if (class_name) {
cb = function(){ $('body').addClass(class_name); }
second_cb = function(){ $('body').removeClass(class_name); }
}
scroll_callbacks.push(function positionedElementTracker(top){
var this_top = $ref.position().top - window_height;
if (top > this_top && (!class_toggled)) {
class_toggled = true;
cb && cb(top);
class_name && $('body').addClass(class_name);
} else if (top < this_top && class_toggled) {
class_toggled = false;
second_cb && second_cb(top);
class_name && $('body').removeClass(class_name);
}
});
return this;
}
// timer loop
setInterval(function(){
if (scrollTick()) {
for (var i = 0; i < scroll_callbacks.length; i++) {
scroll_callbacks[i](scroll_top);
};
$(window).trigger('scrolled', scroll_top);
}
}, event_interval);
}(jQuery));