Reputation: 2859
Browsers made scroll
events asynchronous (i.e. {passive: true}
) a while back. For my use case, synchronous provides a better user experience.
What are the ways to regain synchronous scroll events, so that I can make DOM manipulations whenever the (scrollLeft, scrollTop, clientWidth, clientHeight)
rectangle changes but before the scroll has been rendered?
As a weird workaround, opening and closing Dev Tools in Firefox makes events synchronous, which is how I noticed that synchronous provides a better user experience. Also setting apz.disable_for_scroll_linked_effects
to true makes events synchronous. Also in Safari (desktop) they always seem to be synchronous.
Things I've tried:
div.addEventListener('scroll', update, {passive: false})
but passive: false
is ignored.Object.defineProperty(Object.getPrototypeOf(div), 'scrollTop', {get: ..., set: ...})
but the setter isn't called.div.addEventListener('wheel', update, {passive: false})
but I'm not sure it's possible to map from deltaY
-> updated scrollTop
, plus it doesn't address scrolling via the scrollbar.Upvotes: 2
Views: 549
Reputation: 8002
I do not believe it is possible, you will have to get into the realm of fakery. There is an interesting writeup about how it was (or used to be?) done in code mirror here
The basic idea is to cause a scrollbar to be rendered on some element of the correct height and respond to scroll events on that to update the thing the user actually sees.
Upvotes: 1