mirror of
https://github.com/StarCitizenTools/mediawiki-skins-Citizen.git
synced 2024-11-23 22:13:38 +00:00
refactor(core): ♻️ set up scroll direction observer in setupObservers
This is needed for centralizing the observers.
This commit is contained in:
parent
241ef66893
commit
3b8022c3c1
|
@ -4,36 +4,47 @@
|
|||
* @param {Function} onScrollDown - Function to be called when scrolling down.
|
||||
* @param {Function} onScrollUp - Function to be called when scrolling up.
|
||||
* @param {number} threshold - The threshold for significant scroll position change.
|
||||
* @return {Object}
|
||||
*/
|
||||
function initDirectionObserver( onScrollDown, onScrollUp, threshold ) {
|
||||
function initDirectionObserver( onScrollDown, onScrollUp, threshold = 0 ) {
|
||||
let lastScrollTop = 0;
|
||||
let lastScrollDirection = '';
|
||||
let isScrolling = false;
|
||||
|
||||
window.addEventListener( 'scroll', () => {
|
||||
const handleScroll = () => {
|
||||
const currentScrollTop = window.scrollY;
|
||||
|
||||
if ( Math.abs( currentScrollTop - lastScrollTop ) < threshold ) {
|
||||
isScrolling = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if ( currentScrollTop > lastScrollTop && lastScrollDirection !== 'down' ) {
|
||||
lastScrollDirection = 'down';
|
||||
onScrollDown();
|
||||
} else if ( currentScrollTop < lastScrollTop && lastScrollDirection !== 'up' ) {
|
||||
lastScrollDirection = 'up';
|
||||
onScrollUp();
|
||||
}
|
||||
lastScrollTop = currentScrollTop <= 0 ? 0 : currentScrollTop;
|
||||
isScrolling = false;
|
||||
};
|
||||
|
||||
const onScroll = () => {
|
||||
if ( !isScrolling ) {
|
||||
window.requestAnimationFrame( () => {
|
||||
const currentScrollTop = window.scrollY;
|
||||
|
||||
if ( Math.abs( currentScrollTop - lastScrollTop ) < threshold ) {
|
||||
isScrolling = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if ( currentScrollTop > lastScrollTop && lastScrollDirection !== 'down' ) {
|
||||
lastScrollDirection = 'down';
|
||||
onScrollDown();
|
||||
} else if ( currentScrollTop < lastScrollTop && lastScrollDirection !== 'up' ) {
|
||||
lastScrollDirection = 'up';
|
||||
onScrollUp();
|
||||
}
|
||||
// For Mobile or negative scrolling
|
||||
lastScrollTop = currentScrollTop <= 0 ? 0 : currentScrollTop;
|
||||
isScrolling = false;
|
||||
} );
|
||||
window.requestAnimationFrame( handleScroll );
|
||||
isScrolling = true;
|
||||
}
|
||||
} );
|
||||
};
|
||||
|
||||
return {
|
||||
resume: () => {
|
||||
window.addEventListener( 'scroll', onScroll );
|
||||
},
|
||||
pause: () => {
|
||||
window.removeEventListener( 'scroll', onScroll );
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -3,6 +3,7 @@ const
|
|||
scrollObserver = require( './scrollObserver.js' ),
|
||||
resizeObserver = require( './resizeObserver.js' ),
|
||||
initSectionObserver = require( './sectionObserver.js' ),
|
||||
stickyHeader = require( './stickyHeader.js' ),
|
||||
initTableOfContents = require( './tableOfContents.js' ),
|
||||
deferUntilFrame = require( './deferUntilFrame.js' ),
|
||||
TOC_ID = 'citizen-toc',
|
||||
|
@ -16,7 +17,9 @@ const
|
|||
.map( ( sel ) => `.mw-parser-output ${ sel }` ).join( ', ' ),
|
||||
HEADLINE_SELECTOR = [ '.mw-headline', ...HEADING_TAGS.map( ( tag ) => `${ tag }[id]` ) ]
|
||||
.map( ( sel ) => `.mw-parser-output ${ sel }` ).join( ', ' ),
|
||||
TOC_SECTION_ID_PREFIX = 'toc-';
|
||||
TOC_SECTION_ID_PREFIX = 'toc-',
|
||||
SCROLL_DOWN_CLASS = 'citizen-scroll--down',
|
||||
SCROLL_UP_CLASS = 'citizen-scroll--up';
|
||||
|
||||
/**
|
||||
* @callback OnIntersection
|
||||
|
@ -194,7 +197,27 @@ const main = () => {
|
|||
const tableOfContents = isToCUpdatingAllowed ?
|
||||
setupTableOfContents( tocElement, bodyContent, initSectionObserver ) : null;
|
||||
|
||||
const pagetitleObserver = scrollObserver.initScrollObserver(
|
||||
const stickyIntersection = document.getElementById( 'citizen-page-header-sticky-sentinel' );
|
||||
const isStickyHeaderAllowed = !!stickyIntersection;
|
||||
|
||||
const scrollDirectionObserver = scrollObserver.initDirectionObserver(
|
||||
() => {
|
||||
document.body.classList.remove( SCROLL_UP_CLASS );
|
||||
document.body.classList.add( SCROLL_DOWN_CLASS );
|
||||
},
|
||||
() => {
|
||||
document.body.classList.remove( SCROLL_DOWN_CLASS );
|
||||
document.body.classList.add( SCROLL_UP_CLASS );
|
||||
},
|
||||
50
|
||||
);
|
||||
|
||||
if ( isStickyHeaderAllowed ) {
|
||||
stickyHeader.init();
|
||||
scrollDirectionObserver.resume();
|
||||
}
|
||||
|
||||
const pageHeaderObserver = scrollObserver.initScrollObserver(
|
||||
() => {
|
||||
// TODO: Below page header
|
||||
},
|
||||
|
@ -203,15 +226,20 @@ const main = () => {
|
|||
}
|
||||
);
|
||||
|
||||
pageHeaderObserver.observe( stickyIntersection );
|
||||
|
||||
const bodyObserver = resizeObserver.initResizeObserver(
|
||||
() => {
|
||||
// Disable all CSS transition during resize
|
||||
// Disable all CSS animation during resize
|
||||
if ( document.documentElement.classList.contains( 'citizen-animations-ready' ) ) {
|
||||
document.documentElement.classList.remove( 'citizen-animations-ready' );
|
||||
}
|
||||
scrollDirectionObserver.pause();
|
||||
},
|
||||
() => {
|
||||
// Enable CSS animation after resize is finished
|
||||
document.documentElement.classList.add( 'citizen-animations-ready' );
|
||||
scrollDirectionObserver.resume();
|
||||
}
|
||||
);
|
||||
bodyObserver.observe( document.body );
|
||||
|
|
|
@ -50,14 +50,12 @@ function main( window ) {
|
|||
search = require( './search.js' ),
|
||||
dropdown = require( './dropdown.js' ),
|
||||
setupObservers = require( './setupObservers.js' ),
|
||||
stickyHeader = require( './stickyHeader.js' ),
|
||||
lastModified = require( './lastModified.js' ),
|
||||
share = require( './share.js' );
|
||||
|
||||
dropdown.init();
|
||||
search.init( window );
|
||||
echo();
|
||||
stickyHeader.init();
|
||||
lastModified.init();
|
||||
share.init();
|
||||
|
||||
|
|
|
@ -1,25 +1,5 @@
|
|||
const SCROLL_DOWN_CLASS = 'citizen-scroll--down';
|
||||
const SCROLL_UP_CLASS = 'citizen-scroll--up';
|
||||
const STICKY_CLASS = 'citizen-page-header--sticky';
|
||||
const { initDirectionObserver, initScrollObserver } = require( './scrollObserver.js' );
|
||||
|
||||
/**
|
||||
* Observes the scroll direction and adds/removes corresponding classes to the body element.
|
||||
*
|
||||
* @return {void}
|
||||
*/
|
||||
function observeScrollDirection() {
|
||||
const toggleScrollClass = ( removeClass, addClass ) => () => {
|
||||
window.requestAnimationFrame( () => {
|
||||
document.body.classList.remove( removeClass );
|
||||
document.body.classList.add( addClass );
|
||||
} );
|
||||
};
|
||||
const addScrollDownClass = toggleScrollClass( SCROLL_UP_CLASS, SCROLL_DOWN_CLASS );
|
||||
const addScrollUpClass = toggleScrollClass( SCROLL_DOWN_CLASS, SCROLL_UP_CLASS );
|
||||
|
||||
initDirectionObserver( addScrollDownClass, addScrollUpClass, 50 );
|
||||
}
|
||||
const { initScrollObserver } = require( './scrollObserver.js' );
|
||||
|
||||
/**
|
||||
* Initializes the sticky header functionality for Citizen
|
||||
|
@ -27,13 +7,6 @@ function observeScrollDirection() {
|
|||
* @return {void}
|
||||
*/
|
||||
function init() {
|
||||
const sentinel = document.getElementById( 'citizen-page-header-sticky-sentinel' );
|
||||
const shouldStickyHeader = getComputedStyle( sentinel ).getPropertyValue( 'display' ) !== 'none';
|
||||
if ( !shouldStickyHeader ) {
|
||||
return;
|
||||
}
|
||||
|
||||
observeScrollDirection();
|
||||
const header = document.querySelector( '.citizen-page-header' );
|
||||
const placeholder = document.getElementById( 'citizen-page-header-sticky-placeholder' );
|
||||
let staticHeaderHeight = header.getBoundingClientRect().height;
|
||||
|
@ -89,6 +62,7 @@ function init() {
|
|||
window.removeEventListener( 'resize', onResizeEnd );
|
||||
}
|
||||
);
|
||||
const sentinel = document.getElementById( 'citizen-page-header-sticky-sentinel' );
|
||||
observer.observe( sentinel );
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue