1 | function scrollDir() {
|
2 | const el = document.documentElement;
|
3 | const win = window;
|
4 | const attribute = 'data-scrolldir';
|
5 | const body = document.body;
|
6 | const historyLength = 32;
|
7 | const historyMaxAge = 512;
|
8 | const thresholdPixels = 64;
|
9 | const history = Array(historyLength);
|
10 | let dir = 'down';
|
11 | let e;
|
12 | let pivot;
|
13 | let pivotTime = 0;
|
14 |
|
15 | const tick = function tickFunc() {
|
16 | let y = win.scrollY;
|
17 | const t = e.timeStamp;
|
18 | const furthest = dir === 'down' ? Math.max : Math.min;
|
19 |
|
20 |
|
21 | const yMax = body.offsetHeight - win.innerHeight;
|
22 | y = Math.max(0, y);
|
23 | y = Math.min(yMax, y);
|
24 |
|
25 |
|
26 | history.unshift({ y, t });
|
27 | history.pop();
|
28 |
|
29 |
|
30 | if (y === furthest(pivot, y)) {
|
31 |
|
32 | pivotTime = t;
|
33 | pivot = y;
|
34 | return;
|
35 | }
|
36 |
|
37 |
|
38 |
|
39 | const cutoffTime = t - historyMaxAge;
|
40 | if (cutoffTime > pivotTime) {
|
41 | pivot = y;
|
42 | for (let i = 0; i < historyLength; i += 1) {
|
43 | if (!history[i] || history[i].t < cutoffTime) break;
|
44 | pivot = furthest(pivot, history[i].y);
|
45 | }
|
46 | }
|
47 |
|
48 |
|
49 | if (Math.abs(y - pivot) > thresholdPixels) {
|
50 | pivot = y;
|
51 | pivotTime = t;
|
52 | dir = dir === 'down' ? 'up' : 'down';
|
53 | el.setAttribute(attribute, dir);
|
54 | }
|
55 | };
|
56 |
|
57 | const handler = function handlerFunc(event) {
|
58 | e = event;
|
59 | win.requestAnimationFrame(tick);
|
60 | };
|
61 |
|
62 | pivot = win.scrollY;
|
63 | el.setAttribute(attribute, dir);
|
64 | return win.addEventListener('scroll', handler);
|
65 | }
|
66 | scrollDir();
|