From 3dfc618293ee27a416b942188a2e6e13b049cb3c Mon Sep 17 00:00:00 2001 From: Johannes Raggam Date: Thu, 21 May 2020 13:21:32 +0200 Subject: [PATCH] scroll detection optimization scroll detection: Rework and optimize, set scroll classes on any scrolling event, fix problem with IE and set initial state. Fixes #701 --- CHANGES.md | 1 + src/core/scroll_detection.js | 68 ++++++++++++++++++++++++------------ webpack/base.config.js | 2 +- 3 files changed, 47 insertions(+), 24 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 7c0279fbc..ee5c1d419 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -5,6 +5,7 @@ Features ~~~~~~~~ +- scroll detection: Rework and optimize, set scroll classes on any scrolling event, fix problem with IE and set initial state. Fixes #701 - pat-scroll: To define the scrollable target search also for `overflow-x` and `overflow-y` declarations. - Rework push message support for the STOMP message protocoll instead of backends instead of WAMP. We are using the RabbitMQ message broker for push support instead of crossbar.io. diff --git a/src/core/scroll_detection.js b/src/core/scroll_detection.js index 85aad0d4f..edb19e3a1 100644 --- a/src/core/scroll_detection.js +++ b/src/core/scroll_detection.js @@ -10,35 +10,57 @@ define([ var scroll_detection = { init: function () { - $(window).on('scroll touchmove', function(event) { - if (window.scrollY == 0) { - $("body").addClass("scroll-position-top"); - } else { - $("body").removeClass("scroll-position-top"); - } - // at the bottom of the page - if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) { - $("body").addClass("scroll-position-bottom"); - } else { - $("body").removeClass("scroll-position-bottom"); + + let last_known_scroll_position = 0; + let scroll_y = 0; + let ticking = false; + + let set_scroll_classes = (scroll_pos) => { + document.body.classList.remove("scroll-up"); + document.body.classList.remove("scroll-down"); + document.body.classList.remove("scroll-position-top"); + document.body.classList.remove("scroll-position-bottom"); + + if (scroll_pos < last_known_scroll_position) { + document.body.classList.add("scroll-up"); + } else if (last_known_scroll_position < scroll_pos) { + document.body.classList.add("scroll-down"); } - }); - $(window).on('wheel', function(event) { - // at the top of the page - // Are we scrolling? - if (event.originalEvent.deltaY < 0) { - // up - $("body").addClass("scroll-up").removeClass("scroll-down"); - } else { - // down - $("body").addClass("scroll-down").removeClass("scroll-up"); + if (scroll_pos === 0) { + document.body.classList.add("scroll-position-top"); + } else if ((window.innerHeight + scroll_pos) >= document.body.offsetHeight) { + document.body.classList.add("scroll-position-bottom"); } + } + window.addEventListener('scroll', (e) => { + // In case that's needed sometime: + // ``e.target.scrollTop`` would be the scrolling position of the DOM element. + // We're interested in the window scrolling position though. + if (!ticking) { + // Don't redo while we're already modifying the DOM. + window.requestAnimationFrame(() => { + scroll_y = this.get_scroll_y(); + set_scroll_classes(scroll_y); + last_known_scroll_position = scroll_y; + ticking = false; + }); + ticking = true; + } }); - } + + // Set initial state + $().ready(() => set_scroll_classes(this.get_scroll_y())); + + }, + + get_scroll_y: () => { + return window.scrollY !== undefined ? window.scrollY : window.pageYOffset; // pageYOffset for IE + } }; + scroll_detection.init(); return scroll_detection; -}); \ No newline at end of file +}); diff --git a/webpack/base.config.js b/webpack/base.config.js index 19d4c52b7..6d80b74cb 100644 --- a/webpack/base.config.js +++ b/webpack/base.config.js @@ -36,7 +36,7 @@ module.exports = { module: { rules: [ { - test: /(bumper|patterns|calendar|display-time|equaliser|focus|masonry|push_kit|scroll|tooltip-ng)\.js$/, + test: /(bumper|patterns|calendar|display-time|equaliser|focus|masonry|push_kit|scroll|scroll_detection|tooltip-ng)\.js$/, loader: 'babel-loader', query: { presets: [["@babel/env", {