UNPKG

react-scroll-tracker

Version:

A React hook for tracking scroll depth with TypeScript support and SSR compatibility

79 lines (78 loc) 3.46 kB
"use strict"; var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { if (ar || !(i in from)) { if (!ar) ar = Array.prototype.slice.call(from, 0, i); ar[i] = from[i]; } } return to.concat(ar || Array.prototype.slice.call(from)); }; Object.defineProperty(exports, "__esModule", { value: true }); var react_1 = require("react"); var utils_1 = require("./utils"); var useScrollTracker = function (trackScrollDepths, callback) { var _a = (0, react_1.useState)({ scrollDepths: trackScrollDepths, scrollY: 0 }), state = _a[0], setState = _a[1]; var scrollDepths = state.scrollDepths, scrollY = state.scrollY; (0, react_1.useEffect)(function () { if (typeof window === 'undefined' || window.pageYOffset === 0) { return; } setState(function (oldState) { return (__assign(__assign({}, oldState), { scrollY: window.pageYOffset })); }); }, []); (0, react_1.useEffect)(function () { if (typeof window === 'undefined') { return; } var endScrollTracker = function () { return window.removeEventListener('scroll', handleScroll); }; var handleScroll = function () { var scrollPercent = (0, utils_1.getScrollPercent)(document); if (!scrollDepths) { return setState(function (oldState) { return (__assign(__assign({}, oldState), { scrollY: scrollPercent })); }); } var sortedScrollDepths = __spreadArray([], scrollDepths, true).sort(function (a, b) { return a - b; }); var reachedDepths = sortedScrollDepths.filter(function (depth) { return scrollPercent >= depth; }); var remainingDepths = sortedScrollDepths.filter(function (depth) { return scrollPercent < depth; }); if (reachedDepths.length > 0) { if (remainingDepths.length === 0) { endScrollTracker(); } if (callback) { reachedDepths.forEach(function (depth, i) { // Remaining = unreached depths + reached depths not yet processed var stillRemaining = __spreadArray(__spreadArray([], reachedDepths.slice(i + 1), true), remainingDepths, true); callback({ scrollY: depth, scrollPercent: scrollPercent, remainingDepths: stillRemaining, }); }); } setState({ scrollY: reachedDepths[reachedDepths.length - 1], scrollDepths: remainingDepths, }); } }; window.addEventListener('scroll', handleScroll); return endScrollTracker; }, [scrollDepths, callback]); return { scrollY: scrollY }; }; exports.default = useScrollTracker;