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:
Good
Bad
100, A
100, A
92, A
92, A
88, A
88, A
84, A
84, A
200, B
200, B
197, A
81, A
195, A
79, A
194, A
78, 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.
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":
<div ui-scroll="item in datasource" handle-inertia="false">
Relates to issue https://github.com/angular-ui/ui-scroll/issues/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.