Is there a way to listen for the position of the scroller in a virtuallist? I want to sync two lists.
Hi, you can use JS to synchronize two lists by first visible index:
list1.addEventListener('scroll', () => {
list2.scrollToIndex(list1.firstVisibleIndex);
});
Synchronizing the scroll positions is a bit more involved, but something like this should do it as long as the items have the same heights in both lists:
list1.addEventListener('scroll', () => {
const firstVisibleIndex = list1.firstVisibleIndex;
list2.scrollToIndex(firstVisibleIndex);
// If you also want to sync the exact scroll position...
const firstVisibleElement = [...list1.children].find(
(child) => child.ariaPosInSet === String(firstVisibleIndex + 1),
);
const offset = firstVisibleElement.getBoundingClientRect().top - list1.getBoundingClientRect().top;
list2.scrollTop -= offset;
});
Both are JS code, which would make the solution fragile? Because it depends on the implementation of VirtualList. I hoped for a Java only solution. After all, that is what Flow is about, right? It makes no sense to me to provide a VirtualList component with a scrollToIndex method, but no way to listen for or get the current displayed index. It’s like a half baked cake. ![]()
Anyhow, if this is the only way, then that is the only way. Thanks!
Equivalent in Java would be something like:
list1.getElement().addEventListener("scroll", e -> {
list2.scrollToIndex(e.getEventData().get("event.target.firstVisibleIndex").intValue());
}).addEventData("event.target.firstVisibleIndex").debounce(200);
or
list1.getElement().addEventListener("scroll", e -> {
list1.getElement().executeJs("return this.firstVisibleIndex").then(Integer.class, firstVisibleIndex -> {
list2.scrollToIndex(firstVisibleIndex);
});
}).debounce(200);
but the UX isn’t as nice as syncrhonizing on the client. You don’t want to be sending every scroll event to the server after all.
Fair point. So the proper solution would be to have VirtualList provide a syncTo method, that neatly handles this client side.
Thanks!