7
7
getRangeIndex ,
8
8
getItemTop ,
9
9
GHOST_ITEM_KEY ,
10
+ OriginValues ,
11
+ TargetValues ,
12
+ getSimilarity ,
10
13
} from './util' ;
11
14
12
15
type RenderFunc < T > = ( item : T ) => React . ReactNode ;
@@ -128,12 +131,15 @@ class List<T> extends React.Component<ListProps<T>, ListState> {
128
131
// Re-calculate the scroll position align with the current visible item position
129
132
if ( prevProps . dataSource . length !== dataSource . length && height ) {
130
133
// We will record all the visible item top for next loop match check
131
- const originItemTops : { [ key : string ] : number } = { } ;
134
+ const originItemTops : OriginValues = [ ] ;
132
135
const { startIndex : originStartIndex , itemIndex : originItemIndex } = this . state ;
133
136
let originStartItemTop = this . state . startItemTop ;
134
137
for ( let index = originStartIndex ; index <= originItemIndex ; index += 1 ) {
135
138
const key = this . getItemKey ( index , prevProps ) ;
136
- originItemTops [ key ] = originStartItemTop ;
139
+ originItemTops . push ( {
140
+ key,
141
+ top : originStartItemTop ,
142
+ } ) ;
137
143
originStartItemTop += this . itemElementHeights [ key ] || 0 ;
138
144
}
139
145
@@ -147,7 +153,12 @@ class List<T> extends React.Component<ListProps<T>, ListState> {
147
153
// Loop to get the adjusted item top
148
154
const { scrollHeight, clientHeight } = this . listRef . current ;
149
155
const maxScrollTop = scrollHeight - clientHeight ;
150
- for ( let scrollTop = 0 ; scrollTop <= maxScrollTop ; scrollTop += 1 ) {
156
+
157
+ let bestScrollTop : number | null = null ;
158
+ let bestSimilarity = Number . MAX_VALUE ;
159
+ let debugItemTops : TargetValues = null ;
160
+
161
+ for ( let scrollTop = 0 ; scrollTop < maxScrollTop ; scrollTop += 1 ) {
151
162
const scrollPtg = getScrollPercentage ( { scrollTop, scrollHeight, clientHeight } ) ;
152
163
const visibleCount = Math . ceil ( height / itemHeight ) ;
153
164
@@ -167,14 +178,27 @@ class List<T> extends React.Component<ListProps<T>, ListState> {
167
178
getItemKey : this . getItemKey ,
168
179
} ) ;
169
180
170
- const itemTops : { [ key : string ] : number } = { } ;
171
- for ( let index = itemIndex ; index >= startIndex ; index -= 1 ) {
181
+ const itemTops : TargetValues = { } ;
182
+ for ( let index = itemIndex ; index > startIndex ; index -= 1 ) {
172
183
const key = this . getItemKey ( index ) ;
173
184
itemTops [ key ] = locatedItemTop ;
174
- locatedItemTop -= this . itemElementHeights [ key ] || 0 ;
185
+ const prevItemKey = this . getItemKey ( index - 1 ) ;
186
+ locatedItemTop -= this . itemElementHeights [ prevItemKey ] || 0 ;
175
187
}
176
188
177
- console . log ( '=>' , scrollTop , itemTops ) ;
189
+ const similarity = getSimilarity ( originItemTops , itemTops ) ;
190
+ if ( similarity < bestSimilarity ) {
191
+ bestSimilarity = similarity ;
192
+ bestScrollTop = scrollTop ;
193
+ debugItemTops = itemTops ;
194
+ }
195
+
196
+ console . log ( '=>' , scrollTop , itemTops , getSimilarity ( originItemTops , itemTops ) ) ;
197
+ }
198
+
199
+ if ( bestScrollTop ) {
200
+ console . log ( 'Best Top:' , bestScrollTop , debugItemTops ) ;
201
+ this . listRef . current . scrollTop = bestScrollTop ;
178
202
}
179
203
}
180
204
}
0 commit comments