Skip to content

Added fix for slider scroll - #1433

Open
kevinmeijer97 wants to merge 4 commits into
masterfrom
feature/v5-slider-fix
Open

kevinmeijer97 wants to merge 4 commits into
masterfrom
feature/v5-slider-fix

Conversation

@kevinmeijer97

Copy link
Copy Markdown
Member

On looping sliders (e.g. the store media slider), arrow navigation can misbehave after the browser is resized: a single click may skip several slides, or the slider may appear to jump/loop very quickly.

This happens because loop boundary handling relied on values that go stale after layout changes:

sliderStart / sliderEnd were Vue computeds that read DOM offsetLeft / offsetWidth. Those properties are not reactive, so Vue cached the first computed result. After a resize the real slide offsets change, but the cached bounds do not.
handleLoopBoundary and currentSlide used this.position from useScroll, which can lag behind the actual scrollLeft / scrollTop after a resize (especially with throttling).
Together, that means after a resize the slider can think the current scroll position is outside the “real slides” range and instantly jump by a full set of clones, which looks like skipping many images or looping too fast. Calling useScroll’s measure() alone is not enough, because it only refreshes scroll position, not the cached start/end offsets.

Read loop bounds via methods (getSliderStart / getSliderEnd) so offsets are always taken from the live DOM instead of a cached computed.
In handleLoopBoundary and currentSlide, use the element’s actual scrollLeft / scrollTop for position, while still depending on useScroll’s reactive position so the UI updates during scrolling.

Ref: FW-2744

@indykoning

indykoning commented Oct 15, 2026 •

Copy link
Copy Markdown
Member

Setting and reading directly from/to the DOM you need to take extra care to not cause forced reflows
https://docs.justbetter.nl/snippets/development.html#forced-reflow
Could you double check you're not causing them when scrolling, resizing, etc. after these changes.

UseScroll has an additional observe.mutation option, perhaps that helps with the resizing already
https://vueuse.org/core/useScroll/#:~:text=/**%0A%20%20%20*%20Use-,MutationObserver,-to%20monitor%20specific

DOM operations are expensive which is why we want vue to cache them.
Perhaps https://vueuse.org/core/useElementBounding/ can help us have these values react to resizes and still be cached if no resizes happen (by default useElementBounding listens to resize, and scroll)

@kevinmeijer97

Copy link
Copy Markdown
Member Author

I've updated the approach. Instead of reading the slide positions from the DOM every time we check the loop boundaries, we now cache those values and only recalculate them when the layout actually changes (on resize, and after the loop clones are set up). We also refresh the scroll position from useScroll at that same moment, so it stays in sync after a resize.

That way we still fix the skipping/jumping bug, but avoid extra DOM reads while scrolling.

I looked at useElementBounding and the observe.mutation option on useScroll, they don't quite fit here (useElementBounding is viewport based, and mutation observing doesn't cover pure resizes), so the resize observer we already had seemed like the better place to keep these values up to date.

@Jade-GG
Jade-GG self-requested a review October 20, 2026 09:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants