Created
November 11, 2019 21:24
-
-
Save nmquebb/81d7ab78296947e718f83761a631371a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| let LISTENERS = {}, | |
| LISTENER_IDS = new Set(), | |
| id = 0, | |
| index = 0, | |
| ids = [], | |
| len = 0; | |
| /** | |
| * @name handleOnScroll | |
| * Bind this function to scroll. Iterates over all the listeners | |
| * added via `appendListener` and calls each one. | |
| * @param {object} e native scroll event | |
| */ | |
| export function handleOnScroll(e) { | |
| if (LISTENER_IDS.size == 0) return; | |
| const { scrollY, scrollTop, innerHeight } = window; | |
| ids = [...LISTENER_IDS]; | |
| len = ids.length; | |
| for (; index < len; index++) { | |
| // Calls each listener with a the window's `scrollY` and `innerHeight` values | |
| // that can be passed into `getProgress` along with an element to get it's progress. | |
| LISTENERS[ids[index]](scrollY || scrollTop, innerHeight); | |
| } | |
| } | |
| /** | |
| * @name appendListener | |
| * Add a listener to be called on scroll. | |
| * @param {function} listener function to be triggered on scroll | |
| */ | |
| export function appendListener(listener) { | |
| let listenerId = (id += 1); | |
| LISTENERS[listenerId] = listener; | |
| LISTENER_IDS.add(listenerId); | |
| return () => { | |
| delete LISTENERS[listenerId]; | |
| LISTENER_IDS.delete(listenerId); | |
| }; | |
| } | |
| /** | |
| * @name getProgress | |
| * Utility function useful for getting the progress in a listener. | |
| * @param {object} el element to get progress for | |
| * @param {number} scrollY window scrollY value | |
| * @param {number} innerHeight window innerHeight | |
| */ | |
| export function getProgress(el = {}, scrollY, innerHeight) { | |
| // Navigating via js router can end up calling getProgress without an el | |
| if (!el) return -1; | |
| const calculatedProgress = (scrollY - (el.offsetTop - innerHeight)) / innerHeight; | |
| // Navigation via js router can also cause a NaN calculation | |
| if (!calculatedProgress) return -1; | |
| // If we have a number calculate min/max of 0 or 1 | |
| return calculatedProgress <= 0 | |
| ? 0 | |
| : calculatedProgress <= 1 | |
| ? calculatedProgress | |
| : 1; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment