UNPKG

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