Closed KammererTob closed 2 months ago
I've recently experienced the same behavior. In my case, the elements were added after calling an Apollo mutation and updating the cache, so wasn't sure where the problem was. But, this issue explains the situation pretty well, thanks.
In your reproduction, setTimeout(..., 1)
works better but even that isn't working perfectly. Increasing the timeout makes it work better, e.g. to 200
.
nextTick
is about reactivity and not layout/CSS (which is what the scroll sizes/offsets depend on). What you actually need is to wait for reflow. You can guarantee that reflow had happened if you wait for after the next frame is drawn (aka call requestAnimationFrame
twice).
nextTick
requestAnimationFrame
to triggerrequestAnimationFrame
callback that would guarantee the layout was recalculated for the previous frame renderingResizeObserver
that Quasar uses had definitely triggered and the internal state of Vue/Quasar matches what's in DOM and on the screen - you can call setScrollPosition
or setScrollPercentage
safelyArguably Quasar could wait for requestAnimationFrame
on your behalf, but Quasar is not aware you've made changes that would result in resize of Scroll Area content, so it's probably best that developers implement this logic in their own code.
function addElement() {
elements.value.push(++i);
nextTick(() => {
// DOM was updated by Vue
requestAnimationFrame(() => {
// Browser is about to handle the reflow - the CSS/boundary boxes state is still prior to DOM insertion
requestAnimationFrame(() => {
// Browser had definitely recomputed everything and all had notified Quasar of the new scroll content dimensions
scrollAreaRef.value.setScrollPercentage('horizontal', 1.0, 150);
});
});
});
}
@thexeos Thanks for the explanation and your code example. If there is nothing to "improve" on the Quasar side (maybe apart from mentioning it in the documentation) this can probably be closed.
What happened?
Using
setScrollPercentage
to scroll to the end of the scroll area after adding an element is not working correctly when usingnextTick
. If you usesetTimeout(..., 1)
it works as expected.What did you expect to happen?
It should scroll to the end of the scroll area after adding an element and waiting for the next tick (i.e. after the DOM is updated).
Reproduction URL
https://stackblitz.com/edit/quasarframework-ecbkw4?file=src%2Fpages%2FIndexPage.vue
How to reproduce?
Flavour
Quasar CLI with Vite (@quasar/cli | @quasar/app-vite)
Areas
Components (quasar)
Platforms/Browsers
Firefox
Quasar info output
Relevant log output
No response
Additional context
No response