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 will 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)
Note that import 'lodash-es/debounce'
only imports the debounce
function (and possibly few dependencies) into your JavaScript bundle, not the entire Lodash library.
While you could implement debouncing yourself (using timeouts), Lodash already comes with tests. There is no real reason to implement it yourself.