UNPKG

baseframe-js

Version:

A suite of useful Javascript plugins and functions to help with Front-end Development on websites

65 lines (64 loc) 2.54 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = smoothScroll; var _cashDom = _interopRequireDefault(require("cash-dom")); var _helpers = require("../util/helpers"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } // We need to throttle the checking of the previous scroll for a bug in IOS // that says the previous pixel is the same as the current pixel. // Q: Why do we need to check if the current pixel is the same as the previous? // A: Because it could indicate that the element cannot be completely scrolled to // and as a result we need to break this JS scroll var checkIterationAmt = 3; var activeScroll = false; function smoothScroll(elemYPos) { var _speed = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 100; var afterScroll = arguments.length > 2 ? arguments[2] : undefined; var afterScrollArgs = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : []; // If an active scroll is going exit until it's done if (activeScroll) return; var speed = _speed / 1000; activeScroll = true; var prevScroll = null, animation = null, userBreakScroll = false, pxToCheckIteration = 0; var targetIsAbove = elemYPos < (0, _helpers.docTop)(); (0, _cashDom["default"])(window).on('wheel.smoothScroll', function () { userBreakScroll = true; }); document.body.style.scrollBehavior = 'auto'; var scrollDone = function scrollDone() { if (typeof afterScroll === 'function') { afterScroll.apply(null, afterScrollArgs); } window.cancelAnimationFrame(animation); activeScroll = false; (0, _cashDom["default"])(window).off('wheel.smoothScroll'); document.body.style.scrollBehavior = null; }; (function smoothScrollInner() { var currentScroll = (0, _helpers.docTop)(); if (prevScroll === currentScroll || userBreakScroll) { scrollDone(); return; } if (pxToCheckIteration === checkIterationAmt) { prevScroll = currentScroll; pxToCheckIteration = 0; } else { pxToCheckIteration++; } var isAtTarget = Math.floor(currentScroll - elemYPos) === 0; var isPastTarget = targetIsAbove ? prevScroll < currentScroll : prevScroll > currentScroll; if (!isAtTarget || !isPastTarget) { animation = window.requestAnimationFrame(smoothScrollInner); window.scroll(0, currentScroll + (elemYPos - currentScroll) * speed); } else { scrollDone(); return; } })(); }