Skip to content

Commit

Permalink
feat: ✨ improve scrolling performance
Browse files Browse the repository at this point in the history
  • Loading branch information
alistair3149 committed May 25, 2024
1 parent ae6d207 commit 27bca0f
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 34 deletions.
7 changes: 3 additions & 4 deletions resources/skins.citizen.scripts/scrollObserver.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
/**
* Create an observer based vertical scroll direction
* Create an observer based vertical scroll direction with debouncing
*
* @param {Function} onScrollDown functionality for when viewport is scrolled down
* @param {Function} onScrollUp functionality for when viewport is scrolled up
* @param {number} threshold minimum scrolled px to trigger the function
* @return {void}
*/
function initDirectionObserver( onScrollDown, onScrollUp, threshold ) {
const throttle = require( 'mediawiki.util' ).throttle;

let lastScrollTop = window.scrollY;

const onScroll = () => {
Expand All @@ -26,7 +24,8 @@ function initDirectionObserver( onScrollDown, onScrollUp, threshold ) {
lastScrollTop = scrollTop;
};

window.addEventListener( 'scroll', throttle( onScroll, 250 ) );
const debouncedOnScroll = mw.util.debounce( onScroll, 100 );
window.addEventListener( 'scroll', mw.util.throttle( debouncedOnScroll, 250 ) );
}

/**
Expand Down
64 changes: 34 additions & 30 deletions resources/skins.citizen.scripts/skin.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
const SCROLL_DOWN_CLASS = 'citizen-scroll--down';
const SCROLL_UP_CLASS = 'citizen-scroll--up';
const STICKY_SENTINEL_ID = 'citizen-page-header-sticky-sentinel';
const STICKY_CLASS = 'citizen-page-header--sticky';

/**
* Wait for first paint before calling this function.
* (see T234570#5779890, T246419).
Expand All @@ -10,40 +15,39 @@ function enableCssAnimations( document ) {
}

/**
* Add a class to indicate that sticky header is active
* Initializes the sticky header functionality by setting up scroll observers and intersection observers.
*
* @param {Document} document
* @return {void}
* @param {Document} document - The document object representing the webpage.
*/
function initStickyHeader( document ) {
const scrollObserver = require( './scrollObserver.js' );

// Detect scroll direction and add the right class
scrollObserver.initDirectionObserver(
() => {
document.body.classList.remove( 'citizen-scroll--up' );
document.body.classList.add( 'citizen-scroll--down' );
},
() => {
document.body.classList.remove( 'citizen-scroll--down' );
document.body.classList.add( 'citizen-scroll--up' );
},
10
);

const sentinel = document.getElementById( 'citizen-page-header-sticky-sentinel' );

// In some pages we use display:none to disable the sticky header
// Do not start observer if it is set to display:none
const { initDirectionObserver, initIntersectionObserver } = require( './scrollObserver.js' );

const toggleScrollClass = ( removeClass, addClass ) => {
return () => {
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 );

const toggleStickyClass = () => {
return ( state ) => {
window.requestAnimationFrame( () => {
document.body.classList.toggle( STICKY_CLASS, state );
} );
};
};

initDirectionObserver( addScrollDownClass, addScrollUpClass, 10 );

const sentinel = document.getElementById( STICKY_SENTINEL_ID );

if ( sentinel && getComputedStyle( sentinel ).getPropertyValue( 'display' ) !== 'none' ) {
const observer = scrollObserver.initIntersectionObserver(
() => {
document.body.classList.add( 'citizen-page-header--sticky' );
},
() => {
document.body.classList.remove( 'citizen-page-header--sticky' );
}
);
const observer = initIntersectionObserver( toggleStickyClass( true ), toggleStickyClass( false ) );
observer.observe( sentinel );
}
}
Expand Down

0 comments on commit 27bca0f

Please sign in to comment.