Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Relates to issue #205.
The problem
The update of the scroll position made programmatically can be overridden by the inertia scrolling process, which is handled by the browser internally.
Depends on inertia implementation (Device + OS + Browser).
Irregular, can't be 100%-reproduced.
Details
We have two processes: inertia scrolling (A) and manual scroll position update (B). They may conflict if B happen during A:
During A process Browser calculates the layout iteratively. Next state is based on previous one. B happens between two phases of A. The result depends on A implementation. A developer don't have access to A implementation. Nut sure about specification, but speaking of timing, this is a kind of black box. So A can override B and continue its next phase based on previous A phase, not on B. See Bad scenario.
Solution
The phases of the inertia scrolling process correlate with Browser repaint cycles. To provide right timing, which will not depend on the environment, the code dedicated to update the scroll position can be invoked with the requestAnimationFrame method.
So, basically the fix could be just
This produces an additional asynchronicity, so I decided to provide some optimization and not postpone
scrollTop
change in case it is not necessary. For this purpose I store the value I want to be a new scroll position:and then I re-adjust scroll position on the scroll event handler if current (handled) scroll position is not equal to expected one, which can happen if the inertia process is running:
This produces an asynchronicity, but only in case the inertia does really break the synthetic scrollTop update.
Addition
New attribute had been added:
handle-inertia
. It is responsible for enabling/disabling inertia processing. The default value is "true". To disable inertia scroll processing the value should be set to "false":This attribute is not going to be documented.