Ok guys and gals, here's a tricky one for all you wizards...
I'm working on an immersive web app that overrides the default touch scrolling behavior on mobile devices. The content is divided into pages that use 100% of the viewport and navigation is handled by swiping up and down between pages.
On the first swipe I call requestFullscreen()
on the body
element which, of course, causes a reflow as the viewport resizes. The problem is that I also want that first swipe to trigger the custom scrolling behavior but I'm using Element.nextElementSibling.scrollIntoView({ block : start, behavior : 'smooth' })
and until the reflow is finished the top edge of the next page (an HTMLSectionElement
) is already visible so the scroll doesn't happen.
If I use setTimeout
to wait about 600ms until the reflow is finished the scroll effect works as expected but I'm not happy with this hacky workaround and I'd prefer to use a more elegant async solution.
I first tried triggering the scroll effect from inside the the resolve
executor of the Promise returned by requestFullscreen but that didn't help. This promise resolves very early on in the execution flow.
Then I tried from inside a fullscreenchange
event handler. No luck here either as this event is fired immediately before the fullscreen change happens.
Lastly I tried from inside a window resize
event handler but this fires before the reflow happens. I added a requestIdleCallback
here too but it didn't make any difference.
So my question is... Is there any reliable way to detect the end of a reflow operation? Or alternatively... does anybody have a better Plan B than giving up on using scrollIntoView
and coding my own scroll effect into a window resize handler.