Skip to content

Commit 61574d7

Browse files
committed
handle Safari elasticity effect
1 parent a5078cb commit 61574d7

File tree

2 files changed

+21
-2
lines changed

2 files changed

+21
-2
lines changed

src/List.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
GHOST_ITEM_KEY,
1010
getItemRelativeTop,
1111
getCompareItemRelativeTop,
12+
alignScrollTop,
1213
} from './utils/itemUtil';
1314
import { getIndexByStartLoc, findListDiffIndex } from './utils/algorithmUtil';
1415

@@ -227,7 +228,8 @@ class List<T> extends React.Component<ListProps<T>, ListState<T>> {
227228
public onScroll = () => {
228229
const { dataSource, height, itemHeight, disabled } = this.props;
229230

230-
const { scrollTop } = this.listRef.current;
231+
const { scrollTop: originScrollTop, clientHeight, scrollHeight } = this.listRef.current;
232+
const scrollTop = alignScrollTop(originScrollTop, scrollHeight - clientHeight);
231233

232234
// Skip if `scrollTop` not change to avoid shake
233235
if (scrollTop === this.state.scrollTop || this.lockScroll || disabled) {

src/utils/itemUtil.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,21 @@ function getLocationItem(scrollPtg: number, total: number): LocationItemResult {
3232
};
3333
}
3434

35+
/**
36+
* Safari has the elasticity effect which provides negative `scrollTop` value.
37+
* We should ignore it since will make scroll animation shake.
38+
*/
39+
export function alignScrollTop(scrollTop: number, scrollRange: number) {
40+
if (scrollTop < 0) {
41+
return 0;
42+
}
43+
if (scrollTop >= scrollRange) {
44+
return scrollRange;
45+
}
46+
47+
return scrollTop;
48+
}
49+
3550
export function getScrollPercentage({
3651
scrollTop,
3752
scrollHeight,
@@ -45,7 +60,9 @@ export function getScrollPercentage({
4560
return 0;
4661
}
4762

48-
const scrollTopPtg = scrollTop / (scrollHeight - clientHeight);
63+
const scrollRange = scrollHeight - clientHeight;
64+
const alignedScrollTop = alignScrollTop(scrollTop, scrollRange);
65+
const scrollTopPtg = alignedScrollTop / scrollRange;
4966
return scrollTopPtg;
5067
}
5168

0 commit comments

Comments
 (0)