UNPKG

2.56 kBJavaScriptView Raw
1/**
2 scrolldir - Vertical scroll direction in CSS
3 @version v1.5.0
4 @link https://github.com/dollarshaveclub/scrolldir.git
5 @author Patrick Fisher <patrick@pwfisher.com>
6 @license MIT
7**/
8var attribute = 'data-scrolldir';
9var dir = 'down'; // 'up' or 'down'
10
11var thresholdPixels = 64; // Ignore moves smaller than this.
12
13var el = document.documentElement;
14var win = window;
15var body = document.body;
16var historyLength = 32; // Ticks to keep in history.
17
18var historyMaxAge = 512; // History data time-to-live (ms).
19
20var history = Array(historyLength);
21var e; // last scroll event
22
23var pivot; // "high-water mark"
24
25var pivotTime = 0;
26
27function tick() {
28 var y = win.scrollY || win.pageYOffset;
29 var t = e.timeStamp;
30 var furthest = dir === 'down' ? Math.max : Math.min; // Apply bounds to handle rubber banding
31
32 var yMax = body.scrollHeight - win.innerHeight;
33 y = Math.max(0, y);
34 y = Math.min(yMax, y); // Update history
35
36 history.unshift({
37 y: y,
38 t: t
39 });
40 history.pop(); // Are we continuing in the same direction?
41
42 if (y === furthest(pivot, y)) {
43 // Update "high-water mark" for current direction
44 pivotTime = t;
45 pivot = y;
46 return;
47 } // else we have backed off high-water mark
48 // Apply max age to find current reference point
49
50
51 var cutoffTime = t - historyMaxAge;
52
53 if (cutoffTime > pivotTime) {
54 pivot = y;
55
56 for (var i = 0; i < historyLength; i += 1) {
57 if (!history[i] || history[i].t < cutoffTime) break;
58 pivot = furthest(pivot, history[i].y);
59 }
60 } // Have we exceeded threshold?
61
62
63 if (Math.abs(y - pivot) > thresholdPixels) {
64 pivot = y;
65 pivotTime = t;
66 dir = dir === 'down' ? 'up' : 'down';
67 el.setAttribute(attribute, dir);
68 }
69}
70
71function handler(event) {
72 e = event;
73 return win.requestAnimationFrame(tick);
74}
75
76function scrollDir(opts) {
77 if (opts) {
78 if (opts.attribute) attribute = opts.attribute;
79 if (opts.el) el = opts.el;
80 if (opts.win) win = opts.win;
81 if (opts.dir) dir = opts.dir;
82 if (opts.thresholdPixels) thresholdPixels = opts.thresholdPixels; // If opts.off, turn it off
83 // - set html[data-scrolldir="off"]
84 // - remove the event listener
85
86 if (opts.off === true) {
87 el.setAttribute(attribute, 'off');
88 return win.removeEventListener('scroll', handler);
89 }
90 } // else, turn it on
91 // - set html[data-scrolldir="down"]
92 // - add the event listener
93
94
95 pivot = win.scrollY || win.pageYOffset;
96 el.setAttribute(attribute, dir);
97 return win.addEventListener('scroll', handler);
98}
99
100export default scrollDir;