I've spent a few hours trying to hunt this bug down and I think I finally got a handle on it.
I have an application where I want to scroll to an element smoothly (with animation) on user interaction, but scroll instantly on window resize.
I thought I messed something up with the React states, but as it turns out the issue is that my ResizeObserver fires (at least) once after the initial render, so what happens is that a few tens of milliseconds after the initial scrollIntoView call with animation, a second one without is fired and strangely this freezes the animation midway (instead of either instantly going to the scroll target or not having effect and letting the previous animation finish). I've observed this both with behavior: 'smooth' and behavior: 'instant' or passing different duration in IScrollConfig.
However, if I use the same smooth behavior or the same or longer duration in the second (resize handler) scrollIntoView call, the animation will finish in the right place. Also, if the scroll duration is 100 or shorter in the smooth call, then it still works.
I had a quick look in the code and I'm wondering if this could be a bug with how context and cancelAnimationFrame is handled? Not sure if related, but for Firefox I have to make an immediate call to scrollIntoView inside the ResizeObserver and for Chrome I need to wrap it in requestAnimationFrame to make it work reliably. I guess I could pass forcePolyfill to make them behave the same, but maybe this actually highlights some underlying issue?
I can try creating a reproduction if you have some basic setup I can duplicate so I don't have to set something up from scratch?
I've spent a few hours trying to hunt this bug down and I think I finally got a handle on it.
I have an application where I want to scroll to an element smoothly (with animation) on user interaction, but scroll instantly on window resize.
I thought I messed something up with the React states, but as it turns out the issue is that my
ResizeObserver
fires (at least) once after the initial render, so what happens is that a few tens of milliseconds after the initialscrollIntoView
call with animation, a second one without is fired and strangely this freezes the animation midway (instead of either instantly going to the scroll target or not having effect and letting the previous animation finish). I've observed this both withbehavior: 'smooth'
andbehavior: 'instant'
or passing differentduration
inIScrollConfig
.However, if I use the same
smooth
behavior or the same or longer duration in the second (resize handler)scrollIntoView
call, the animation will finish in the right place. Also, if the scroll duration is 100 or shorter in the smooth call, then it still works.I had a quick look in the code and I'm wondering if this could be a bug with how
context
andcancelAnimationFrame
is handled? Not sure if related, but for Firefox I have to make an immediate call toscrollIntoView
inside theResizeObserver
and for Chrome I need to wrap it inrequestAnimationFrame
to make it work reliably. I guess I could passforcePolyfill
to make them behave the same, but maybe this actually highlights some underlying issue?I can try creating a reproduction if you have some basic setup I can duplicate so I don't have to set something up from scratch?