JavaScript: Detecting the end of native smooth scrolling

Updated . Posted . Visible to the public.

When you use native smooth scrolling Show archive.org snapshot there is no built-in method to detect the end of the scrolling animation. Methods like scrollTo() Show archive.org snapshot don't return a promise. We may eventually get a scrollend Show archive.org snapshot event, but that is still some time away Show archive.org snapshot .

Until then I'm using the following awaitScrollEnd() function as a workaround. It returns a promise that resolves when the given Document or Element does not receive a scroll event for 75 milliseconds:

import debounce from 'lodash-es/debounce'

function awaitScrollEnd(viewport, delay = 75) {
  return new Promise((resolve) => {
    function done() {
      viewport.removeEventListener('scroll', debouncedDone)
      resolve()
    }

    // We consider scrolling to have stopped after we haven't received
    // a `scroll` event for `delay` milliseconds.
    //
    // The default delay (75) assumes a minimum framerate of ~13 FPS
    // while scrolling.
    let debouncedDone = debounce(done, delay)
    viewport.addEventListener('scroll', debouncedDone, { passive: true })
    debouncedDone()
  })
}

Use it after you started a native scrolling motion:

element.scrollIntoView({ behavior: 'smooth' })
await awaitScrollEnd(document)
Henning Koch
Last edit
Henning Koch
License
Source code in this card is licensed under the MIT License.
Posted by Henning Koch to makandra dev (2023-05-09 14:26)