@@ -178,7 +178,6 @@ export const observeElementOffset = <T extends Element>(
178178 }
179179 const handler = createHandler ( true )
180180 const endHandler = createHandler ( false )
181- endHandler ( )
182181
183182 element . addEventListener ( 'scroll' , handler , addEventListenerOptions )
184183 const registerScrollendEvent =
@@ -226,7 +225,6 @@ export const observeWindowOffset = (
226225 }
227226 const handler = createHandler ( true )
228227 const endHandler = createHandler ( false )
229- endHandler ( )
230228
231229 element . addEventListener ( 'scroll' , handler , addEventListenerOptions )
232230 const registerScrollendEvent =
@@ -359,6 +357,7 @@ export class Virtualizer<
359357 scrollElement : TScrollElement | null = null
360358 targetWindow : ( Window & typeof globalThis ) | null = null
361359 isScrolling = false
360+ private currentScrollToIndex : number | null = null
362361 measurementsCache : Array < VirtualItem > = [ ]
363362 private itemSizeCache = new Map < Key , number > ( )
364363 private laneAssignments = new Map < number , number > ( ) // index → lane cache
@@ -518,11 +517,6 @@ export class Virtualizer<
518517 this . observer . observe ( cached )
519518 } )
520519
521- this . _scrollToOffset ( this . getScrollOffset ( ) , {
522- adjustments : undefined ,
523- behavior : undefined ,
524- } )
525-
526520 this . unsubs . push (
527521 this . options . observeElementRect ( this , ( rect ) => {
528522 this . scrollRect = rect
@@ -544,6 +538,11 @@ export class Virtualizer<
544538 this . maybeNotify ( )
545539 } ) ,
546540 )
541+
542+ this . _scrollToOffset ( this . getScrollOffset ( ) , {
543+ adjustments : undefined ,
544+ behavior : undefined ,
545+ } )
547546 }
548547 }
549548
@@ -1085,6 +1084,7 @@ export class Virtualizer<
10851084 }
10861085
10871086 index = Math . max ( 0 , Math . min ( index , this . options . count - 1 ) )
1087+ this . currentScrollToIndex = index
10881088
10891089 let attempts = 0
10901090 const maxAttempts = 10
@@ -1101,22 +1101,37 @@ export class Virtualizer<
11011101 this . _scrollToOffset ( offset , { adjustments : undefined , behavior } )
11021102
11031103 this . targetWindow . requestAnimationFrame ( ( ) => {
1104- const currentOffset = this . getScrollOffset ( )
1105- const afterInfo = this . getOffsetForIndex ( index , align )
1106- if ( ! afterInfo ) {
1107- console . warn ( 'Failed to get offset for index:' , index )
1108- return
1104+ const verify = ( ) => {
1105+ // Abort if a new scrollToIndex was called with a different index
1106+ if ( this . currentScrollToIndex !== index ) return
1107+
1108+ const currentOffset = this . getScrollOffset ( )
1109+ const afterInfo = this . getOffsetForIndex ( index , align )
1110+ if ( ! afterInfo ) {
1111+ console . warn ( 'Failed to get offset for index:' , index )
1112+ return
1113+ }
1114+
1115+ if ( ! approxEqual ( afterInfo [ 0 ] , currentOffset ) ) {
1116+ scheduleRetry ( align )
1117+ }
11091118 }
11101119
1111- if ( ! approxEqual ( afterInfo [ 0 ] , currentOffset ) ) {
1112- scheduleRetry ( align )
1120+ // In dynamic mode, wait an extra frame for ResizeObserver to measure newly visible elements
1121+ if ( this . isDynamicMode ( ) ) {
1122+ this . targetWindow ! . requestAnimationFrame ( verify )
1123+ } else {
1124+ verify ( )
11131125 }
11141126 } )
11151127 }
11161128
11171129 const scheduleRetry = ( align : ScrollAlignment ) => {
11181130 if ( ! this . targetWindow ) return
11191131
1132+ // Abort if a new scrollToIndex was called with a different index
1133+ if ( this . currentScrollToIndex !== index ) return
1134+
11201135 attempts ++
11211136 if ( attempts < maxAttempts ) {
11221137 if ( process . env . NODE_ENV !== 'production' && this . options . debug ) {
0 commit comments