From e31de7e0a009941669b2eac1644b61b0527245cc Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Tue, 18 Aug 2026 12:17:51 +0200 Subject: [PATCH] Improve the `watchScroll` helper function a little bit Note how the "scroll" event handler function is attached to the `state`-object, despite that property not being used anywhere in the code-base. This originated in PR 5295, over a decade ago, however the property appears to have been unused from the start; hence let's just remove it now. Additionally, define the "scroll" event handler function inline and create the `requestAnimationFrame` callback function just once rather than for every new "scroll" event. --- web/ui_utils.js | 51 +++++++++++++++++++++++-------------------------- 1 file changed, 24 insertions(+), 27 deletions(-) diff --git a/web/ui_utils.js b/web/ui_utils.js index b7c52ab226b33..38dc6feccbfd3 100644 --- a/web/ui_utils.js +++ b/web/ui_utils.js @@ -117,43 +117,40 @@ function scrollIntoView(element, spot) { * PDF.js friendly one: with scroll debounce and scroll direction. */ function watchScroll(viewAreaElement, callback, abortSignal = undefined) { - const debounceScroll = function (evt) { - if (rAF) { - return; + function onRAF() { + rAF = null; + + const currentX = viewAreaElement.scrollLeft; + const lastX = state.lastX; + if (currentX !== lastX) { + state.right = currentX > lastX; } - // schedule an invocation of scroll for next animation frame. - rAF = window.requestAnimationFrame(function viewAreaElementScrolled() { - rAF = null; - - const currentX = viewAreaElement.scrollLeft; - const lastX = state.lastX; - if (currentX !== lastX) { - state.right = currentX > lastX; - } - state.lastX = currentX; - const currentY = viewAreaElement.scrollTop; - const lastY = state.lastY; - if (currentY !== lastY) { - state.down = currentY > lastY; - } - state.lastY = currentY; - callback(state); - }); - }; + state.lastX = currentX; + const currentY = viewAreaElement.scrollTop; + const lastY = state.lastY; + if (currentY !== lastY) { + state.down = currentY > lastY; + } + state.lastY = currentY; + callback(state); + } const state = { right: true, down: true, lastX: viewAreaElement.scrollLeft, lastY: viewAreaElement.scrollTop, - _eventHandler: debounceScroll, }; let rAF = null; - viewAreaElement.addEventListener("scroll", debounceScroll, { - useCapture: true, - signal: abortSignal, - }); + viewAreaElement.addEventListener( + "scroll", + () => { + // Schedule an invocation of scroll for next animation frame, when needed. + rAF ??= window.requestAnimationFrame(onRAF); + }, + { useCapture: true, signal: abortSignal } + ); abortSignal?.addEventListener( "abort", () => window.cancelAnimationFrame(rAF),