@tanstack/virtual-core 3.5.0 → 3.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.cjs +136 -68
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +8 -5
- package/dist/cjs/utils.cjs +3 -3
- package/dist/cjs/utils.cjs.map +1 -1
- package/dist/cjs/utils.d.cts +1 -1
- package/dist/esm/index.d.ts +8 -5
- package/dist/esm/index.js +136 -68
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/utils.d.ts +1 -1
- package/dist/esm/utils.js +3 -3
- package/dist/esm/utils.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +160 -84
- package/src/utils.ts +8 -4
package/src/index.ts
CHANGED
|
@@ -67,6 +67,10 @@ export const observeElementRect = <T extends Element>(
|
|
|
67
67
|
if (!element) {
|
|
68
68
|
return
|
|
69
69
|
}
|
|
70
|
+
const targetWindow = instance.targetWindow
|
|
71
|
+
if (!targetWindow) {
|
|
72
|
+
return
|
|
73
|
+
}
|
|
70
74
|
|
|
71
75
|
const handler = (rect: Rect) => {
|
|
72
76
|
const { width, height } = rect
|
|
@@ -75,11 +79,11 @@ export const observeElementRect = <T extends Element>(
|
|
|
75
79
|
|
|
76
80
|
handler(element.getBoundingClientRect())
|
|
77
81
|
|
|
78
|
-
if (
|
|
82
|
+
if (!targetWindow.ResizeObserver) {
|
|
79
83
|
return () => {}
|
|
80
84
|
}
|
|
81
85
|
|
|
82
|
-
const observer = new ResizeObserver((entries) => {
|
|
86
|
+
const observer = new targetWindow.ResizeObserver((entries) => {
|
|
83
87
|
const entry = entries[0]
|
|
84
88
|
if (entry?.borderBoxSize) {
|
|
85
89
|
const box = entry.borderBoxSize[0]
|
|
@@ -134,13 +138,21 @@ export const observeElementOffset = <T extends Element>(
|
|
|
134
138
|
if (!element) {
|
|
135
139
|
return
|
|
136
140
|
}
|
|
141
|
+
const targetWindow = instance.targetWindow
|
|
142
|
+
if (!targetWindow) {
|
|
143
|
+
return
|
|
144
|
+
}
|
|
137
145
|
|
|
138
146
|
let offset = 0
|
|
139
147
|
const fallback = supportsScrollend
|
|
140
148
|
? () => undefined
|
|
141
|
-
: debounce(
|
|
142
|
-
|
|
143
|
-
|
|
149
|
+
: debounce(
|
|
150
|
+
targetWindow,
|
|
151
|
+
() => {
|
|
152
|
+
cb(offset, false)
|
|
153
|
+
},
|
|
154
|
+
instance.options.isScrollingResetDelay,
|
|
155
|
+
)
|
|
144
156
|
|
|
145
157
|
const createHandler = (isScrolling: boolean) => () => {
|
|
146
158
|
offset = element[instance.options.horizontal ? 'scrollLeft' : 'scrollTop']
|
|
@@ -168,13 +180,21 @@ export const observeWindowOffset = (
|
|
|
168
180
|
if (!element) {
|
|
169
181
|
return
|
|
170
182
|
}
|
|
183
|
+
const targetWindow = instance.targetWindow
|
|
184
|
+
if (!targetWindow) {
|
|
185
|
+
return
|
|
186
|
+
}
|
|
171
187
|
|
|
172
188
|
let offset = 0
|
|
173
189
|
const fallback = supportsScrollend
|
|
174
190
|
? () => undefined
|
|
175
|
-
: debounce(
|
|
176
|
-
|
|
177
|
-
|
|
191
|
+
: debounce(
|
|
192
|
+
targetWindow,
|
|
193
|
+
() => {
|
|
194
|
+
cb(offset, false)
|
|
195
|
+
},
|
|
196
|
+
instance.options.isScrollingResetDelay,
|
|
197
|
+
)
|
|
178
198
|
|
|
179
199
|
const createHandler = (isScrolling: boolean) => () => {
|
|
180
200
|
offset = element[instance.options.horizontal ? 'scrollX' : 'scrollY']
|
|
@@ -298,6 +318,7 @@ export interface VirtualizerOptions<
|
|
|
298
318
|
initialMeasurementsCache?: VirtualItem[]
|
|
299
319
|
lanes?: number
|
|
300
320
|
isScrollingResetDelay?: number
|
|
321
|
+
enabled?: boolean
|
|
301
322
|
}
|
|
302
323
|
|
|
303
324
|
export class Virtualizer<
|
|
@@ -307,13 +328,14 @@ export class Virtualizer<
|
|
|
307
328
|
private unsubs: (void | (() => void))[] = []
|
|
308
329
|
options!: Required<VirtualizerOptions<TScrollElement, TItemElement>>
|
|
309
330
|
scrollElement: TScrollElement | null = null
|
|
331
|
+
targetWindow: (Window & typeof globalThis) | null = null
|
|
310
332
|
isScrolling: boolean = false
|
|
311
|
-
private scrollToIndexTimeoutId:
|
|
333
|
+
private scrollToIndexTimeoutId: number | null = null
|
|
312
334
|
measurementsCache: VirtualItem[] = []
|
|
313
335
|
private itemSizeCache = new Map<Key, number>()
|
|
314
336
|
private pendingMeasuredCacheIndexes: number[] = []
|
|
315
|
-
scrollRect: Rect
|
|
316
|
-
scrollOffset: number
|
|
337
|
+
scrollRect: Rect | null = null
|
|
338
|
+
scrollOffset: number | null = null
|
|
317
339
|
scrollDirection: ScrollDirection | null = null
|
|
318
340
|
private scrollAdjustments: number = 0
|
|
319
341
|
shouldAdjustScrollPositionOnItemSizeChange:
|
|
@@ -330,15 +352,17 @@ export class Virtualizer<
|
|
|
330
352
|
const get = () => {
|
|
331
353
|
if (_ro) {
|
|
332
354
|
return _ro
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
this._measureElement(entry.target as TItemElement, entry)
|
|
337
|
-
})
|
|
338
|
-
}))
|
|
339
|
-
} else {
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
if (!this.targetWindow || !this.targetWindow.ResizeObserver) {
|
|
340
358
|
return null
|
|
341
359
|
}
|
|
360
|
+
|
|
361
|
+
return (_ro = new this.targetWindow.ResizeObserver((entries) => {
|
|
362
|
+
entries.forEach((entry) => {
|
|
363
|
+
this._measureElement(entry.target as TItemElement, entry)
|
|
364
|
+
})
|
|
365
|
+
}))
|
|
342
366
|
}
|
|
343
367
|
|
|
344
368
|
return {
|
|
@@ -352,17 +376,6 @@ export class Virtualizer<
|
|
|
352
376
|
|
|
353
377
|
constructor(opts: VirtualizerOptions<TScrollElement, TItemElement>) {
|
|
354
378
|
this.setOptions(opts)
|
|
355
|
-
this.scrollRect = this.options.initialRect
|
|
356
|
-
this.scrollOffset =
|
|
357
|
-
typeof this.options.initialOffset === 'function'
|
|
358
|
-
? this.options.initialOffset()
|
|
359
|
-
: this.options.initialOffset
|
|
360
|
-
this.measurementsCache = this.options.initialMeasurementsCache
|
|
361
|
-
this.measurementsCache.forEach((item) => {
|
|
362
|
-
this.itemSizeCache.set(item.key, item.size)
|
|
363
|
-
})
|
|
364
|
-
|
|
365
|
-
this.notify(false, false)
|
|
366
379
|
}
|
|
367
380
|
|
|
368
381
|
setOptions = (opts: VirtualizerOptions<TScrollElement, TItemElement>) => {
|
|
@@ -390,6 +403,7 @@ export class Virtualizer<
|
|
|
390
403
|
initialMeasurementsCache: [],
|
|
391
404
|
lanes: 1,
|
|
392
405
|
isScrollingResetDelay: 150,
|
|
406
|
+
enabled: true,
|
|
393
407
|
...opts,
|
|
394
408
|
}
|
|
395
409
|
}
|
|
@@ -414,25 +428,39 @@ export class Virtualizer<
|
|
|
414
428
|
this.unsubs.filter(Boolean).forEach((d) => d!())
|
|
415
429
|
this.unsubs = []
|
|
416
430
|
this.scrollElement = null
|
|
431
|
+
this.targetWindow = null
|
|
432
|
+
this.observer.disconnect()
|
|
433
|
+
this.measureElementCache.clear()
|
|
417
434
|
}
|
|
418
435
|
|
|
419
436
|
_didMount = () => {
|
|
420
|
-
this.measureElementCache.forEach(this.observer.observe)
|
|
421
437
|
return () => {
|
|
422
|
-
this.observer.disconnect()
|
|
423
438
|
this.cleanup()
|
|
424
439
|
}
|
|
425
440
|
}
|
|
426
441
|
|
|
427
442
|
_willUpdate = () => {
|
|
428
|
-
const scrollElement = this.options.
|
|
443
|
+
const scrollElement = this.options.enabled
|
|
444
|
+
? this.options.getScrollElement()
|
|
445
|
+
: null
|
|
429
446
|
|
|
430
447
|
if (this.scrollElement !== scrollElement) {
|
|
431
448
|
this.cleanup()
|
|
432
449
|
|
|
450
|
+
if (!scrollElement) {
|
|
451
|
+
this.notify(false, false)
|
|
452
|
+
return
|
|
453
|
+
}
|
|
454
|
+
|
|
433
455
|
this.scrollElement = scrollElement
|
|
434
456
|
|
|
435
|
-
this.
|
|
457
|
+
if (this.scrollElement && 'ownerDocument' in this.scrollElement) {
|
|
458
|
+
this.targetWindow = this.scrollElement.ownerDocument.defaultView
|
|
459
|
+
} else {
|
|
460
|
+
this.targetWindow = this.scrollElement?.window ?? null
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
this._scrollToOffset(this.getScrollOffset(), {
|
|
436
464
|
adjustments: undefined,
|
|
437
465
|
behavior: undefined,
|
|
438
466
|
})
|
|
@@ -448,7 +476,7 @@ export class Virtualizer<
|
|
|
448
476
|
this.options.observeElementOffset(this, (offset, isScrolling) => {
|
|
449
477
|
this.scrollAdjustments = 0
|
|
450
478
|
this.scrollDirection = isScrolling
|
|
451
|
-
? this.
|
|
479
|
+
? this.getScrollOffset() < offset
|
|
452
480
|
? 'forward'
|
|
453
481
|
: 'backward'
|
|
454
482
|
: null
|
|
@@ -464,29 +492,30 @@ export class Virtualizer<
|
|
|
464
492
|
}
|
|
465
493
|
|
|
466
494
|
private getSize = () => {
|
|
495
|
+
if (!this.options.enabled) {
|
|
496
|
+
this.scrollRect = null
|
|
497
|
+
return 0
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
this.scrollRect = this.scrollRect ?? this.options.initialRect
|
|
501
|
+
|
|
467
502
|
return this.scrollRect[this.options.horizontal ? 'width' : 'height']
|
|
468
503
|
}
|
|
469
504
|
|
|
470
|
-
private
|
|
471
|
-
()
|
|
472
|
-
this.
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
this.
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
}
|
|
485
|
-
},
|
|
486
|
-
{
|
|
487
|
-
key: false,
|
|
488
|
-
},
|
|
489
|
-
)
|
|
505
|
+
private getScrollOffset = () => {
|
|
506
|
+
if (!this.options.enabled) {
|
|
507
|
+
this.scrollOffset = null
|
|
508
|
+
return 0
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
this.scrollOffset =
|
|
512
|
+
this.scrollOffset ??
|
|
513
|
+
(typeof this.options.initialOffset === 'function'
|
|
514
|
+
? this.options.initialOffset()
|
|
515
|
+
: this.options.initialOffset)
|
|
516
|
+
|
|
517
|
+
return this.scrollOffset
|
|
518
|
+
}
|
|
490
519
|
|
|
491
520
|
private getFurthestMeasurement = (
|
|
492
521
|
measurements: VirtualItem[],
|
|
@@ -529,9 +558,48 @@ export class Virtualizer<
|
|
|
529
558
|
: undefined
|
|
530
559
|
}
|
|
531
560
|
|
|
561
|
+
private getMeasurementOptions = memo(
|
|
562
|
+
() => [
|
|
563
|
+
this.options.count,
|
|
564
|
+
this.options.paddingStart,
|
|
565
|
+
this.options.scrollMargin,
|
|
566
|
+
this.options.getItemKey,
|
|
567
|
+
this.options.enabled,
|
|
568
|
+
],
|
|
569
|
+
(count, paddingStart, scrollMargin, getItemKey, enabled) => {
|
|
570
|
+
this.pendingMeasuredCacheIndexes = []
|
|
571
|
+
return {
|
|
572
|
+
count,
|
|
573
|
+
paddingStart,
|
|
574
|
+
scrollMargin,
|
|
575
|
+
getItemKey,
|
|
576
|
+
enabled,
|
|
577
|
+
}
|
|
578
|
+
},
|
|
579
|
+
{
|
|
580
|
+
key: false,
|
|
581
|
+
},
|
|
582
|
+
)
|
|
583
|
+
|
|
532
584
|
private getMeasurements = memo(
|
|
533
585
|
() => [this.getMeasurementOptions(), this.itemSizeCache],
|
|
534
|
-
(
|
|
586
|
+
(
|
|
587
|
+
{ count, paddingStart, scrollMargin, getItemKey, enabled },
|
|
588
|
+
itemSizeCache,
|
|
589
|
+
) => {
|
|
590
|
+
if (!enabled) {
|
|
591
|
+
this.measurementsCache = []
|
|
592
|
+
this.itemSizeCache.clear()
|
|
593
|
+
return []
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
if (this.measurementsCache.length === 0) {
|
|
597
|
+
this.measurementsCache = this.options.initialMeasurementsCache
|
|
598
|
+
this.measurementsCache.forEach((item) => {
|
|
599
|
+
this.itemSizeCache.set(item.key, item.size)
|
|
600
|
+
})
|
|
601
|
+
}
|
|
602
|
+
|
|
535
603
|
const min =
|
|
536
604
|
this.pendingMeasuredCacheIndexes.length > 0
|
|
537
605
|
? Math.min(...this.pendingMeasuredCacheIndexes)
|
|
@@ -585,7 +653,7 @@ export class Virtualizer<
|
|
|
585
653
|
)
|
|
586
654
|
|
|
587
655
|
calculateRange = memo(
|
|
588
|
-
() => [this.getMeasurements(), this.getSize(), this.
|
|
656
|
+
() => [this.getMeasurements(), this.getSize(), this.getScrollOffset()],
|
|
589
657
|
(measurements, outerSize, scrollOffset) => {
|
|
590
658
|
return (this.range =
|
|
591
659
|
measurements.length > 0 && outerSize > 0
|
|
@@ -643,7 +711,7 @@ export class Virtualizer<
|
|
|
643
711
|
node: TItemElement,
|
|
644
712
|
entry: ResizeObserverEntry | undefined,
|
|
645
713
|
) => {
|
|
646
|
-
const item = this.
|
|
714
|
+
const item = this.getMeasurements()[this.indexFromElement(node)]
|
|
647
715
|
|
|
648
716
|
if (!item || !node.isConnected) {
|
|
649
717
|
this.measureElementCache.forEach((cached, key) => {
|
|
@@ -678,13 +746,13 @@ export class Virtualizer<
|
|
|
678
746
|
if (
|
|
679
747
|
this.shouldAdjustScrollPositionOnItemSizeChange !== undefined
|
|
680
748
|
? this.shouldAdjustScrollPositionOnItemSizeChange(item, delta, this)
|
|
681
|
-
: item.start < this.
|
|
749
|
+
: item.start < this.getScrollOffset() + this.scrollAdjustments
|
|
682
750
|
) {
|
|
683
751
|
if (process.env.NODE_ENV !== 'production' && this.options.debug) {
|
|
684
752
|
console.info('correction', delta)
|
|
685
753
|
}
|
|
686
754
|
|
|
687
|
-
this._scrollToOffset(this.
|
|
755
|
+
this._scrollToOffset(this.getScrollOffset(), {
|
|
688
756
|
adjustments: (this.scrollAdjustments += delta),
|
|
689
757
|
behavior: undefined,
|
|
690
758
|
})
|
|
@@ -727,7 +795,9 @@ export class Virtualizer<
|
|
|
727
795
|
|
|
728
796
|
getVirtualItemForOffset = (offset: number) => {
|
|
729
797
|
const measurements = this.getMeasurements()
|
|
730
|
-
|
|
798
|
+
if (measurements.length === 0) {
|
|
799
|
+
return undefined
|
|
800
|
+
}
|
|
731
801
|
return notUndefined(
|
|
732
802
|
measurements[
|
|
733
803
|
findNearestBinarySearch(
|
|
@@ -742,11 +812,12 @@ export class Virtualizer<
|
|
|
742
812
|
|
|
743
813
|
getOffsetForAlignment = (toOffset: number, align: ScrollAlignment) => {
|
|
744
814
|
const size = this.getSize()
|
|
815
|
+
const scrollOffset = this.getScrollOffset()
|
|
745
816
|
|
|
746
817
|
if (align === 'auto') {
|
|
747
|
-
if (toOffset <=
|
|
818
|
+
if (toOffset <= scrollOffset) {
|
|
748
819
|
align = 'start'
|
|
749
|
-
} else if (toOffset >=
|
|
820
|
+
} else if (toOffset >= scrollOffset + size) {
|
|
750
821
|
align = 'end'
|
|
751
822
|
} else {
|
|
752
823
|
align = 'start'
|
|
@@ -770,7 +841,7 @@ export class Virtualizer<
|
|
|
770
841
|
: this.scrollElement[scrollSizeProp]
|
|
771
842
|
: 0
|
|
772
843
|
|
|
773
|
-
const maxOffset = scrollSize -
|
|
844
|
+
const maxOffset = scrollSize - size
|
|
774
845
|
|
|
775
846
|
return Math.max(Math.min(maxOffset, toOffset), 0)
|
|
776
847
|
}
|
|
@@ -778,28 +849,28 @@ export class Virtualizer<
|
|
|
778
849
|
getOffsetForIndex = (index: number, align: ScrollAlignment = 'auto') => {
|
|
779
850
|
index = Math.max(0, Math.min(index, this.options.count - 1))
|
|
780
851
|
|
|
781
|
-
const
|
|
852
|
+
const item = this.getMeasurements()[index]
|
|
853
|
+
if (!item) {
|
|
854
|
+
return undefined
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
const size = this.getSize()
|
|
858
|
+
const scrollOffset = this.getScrollOffset()
|
|
782
859
|
|
|
783
860
|
if (align === 'auto') {
|
|
784
|
-
if (
|
|
785
|
-
measurement.end >=
|
|
786
|
-
this.scrollOffset + this.getSize() - this.options.scrollPaddingEnd
|
|
787
|
-
) {
|
|
861
|
+
if (item.end >= scrollOffset + size - this.options.scrollPaddingEnd) {
|
|
788
862
|
align = 'end'
|
|
789
|
-
} else if (
|
|
790
|
-
measurement.start <=
|
|
791
|
-
this.scrollOffset + this.options.scrollPaddingStart
|
|
792
|
-
) {
|
|
863
|
+
} else if (item.start <= scrollOffset + this.options.scrollPaddingStart) {
|
|
793
864
|
align = 'start'
|
|
794
865
|
} else {
|
|
795
|
-
return [
|
|
866
|
+
return [scrollOffset, align] as const
|
|
796
867
|
}
|
|
797
868
|
}
|
|
798
869
|
|
|
799
870
|
const toOffset =
|
|
800
871
|
align === 'end'
|
|
801
|
-
?
|
|
802
|
-
:
|
|
872
|
+
? item.end + this.options.scrollPaddingEnd
|
|
873
|
+
: item.start - this.options.scrollPaddingStart
|
|
803
874
|
|
|
804
875
|
return [this.getOffsetForAlignment(toOffset, align), align] as const
|
|
805
876
|
}
|
|
@@ -807,8 +878,8 @@ export class Virtualizer<
|
|
|
807
878
|
private isDynamicMode = () => this.measureElementCache.size > 0
|
|
808
879
|
|
|
809
880
|
private cancelScrollToIndex = () => {
|
|
810
|
-
if (this.scrollToIndexTimeoutId !== null) {
|
|
811
|
-
clearTimeout(this.scrollToIndexTimeoutId)
|
|
881
|
+
if (this.scrollToIndexTimeoutId !== null && this.targetWindow) {
|
|
882
|
+
this.targetWindow.clearTimeout(this.scrollToIndexTimeoutId)
|
|
812
883
|
this.scrollToIndexTimeoutId = null
|
|
813
884
|
}
|
|
814
885
|
}
|
|
@@ -845,12 +916,15 @@ export class Virtualizer<
|
|
|
845
916
|
)
|
|
846
917
|
}
|
|
847
918
|
|
|
848
|
-
const
|
|
919
|
+
const offsetAndAlign = this.getOffsetForIndex(index, initialAlign)
|
|
920
|
+
if (!offsetAndAlign) return
|
|
921
|
+
|
|
922
|
+
const [offset, align] = offsetAndAlign
|
|
849
923
|
|
|
850
|
-
this._scrollToOffset(
|
|
924
|
+
this._scrollToOffset(offset, { adjustments: undefined, behavior })
|
|
851
925
|
|
|
852
|
-
if (behavior !== 'smooth' && this.isDynamicMode()) {
|
|
853
|
-
this.scrollToIndexTimeoutId = setTimeout(() => {
|
|
926
|
+
if (behavior !== 'smooth' && this.isDynamicMode() && this.targetWindow) {
|
|
927
|
+
this.scrollToIndexTimeoutId = this.targetWindow.setTimeout(() => {
|
|
854
928
|
this.scrollToIndexTimeoutId = null
|
|
855
929
|
|
|
856
930
|
const elementInDOM = this.measureElementCache.has(
|
|
@@ -858,9 +932,11 @@ export class Virtualizer<
|
|
|
858
932
|
)
|
|
859
933
|
|
|
860
934
|
if (elementInDOM) {
|
|
861
|
-
const [
|
|
935
|
+
const [latestOffset] = notUndefined(
|
|
936
|
+
this.getOffsetForIndex(index, align),
|
|
937
|
+
)
|
|
862
938
|
|
|
863
|
-
if (!approxEqual(
|
|
939
|
+
if (!approxEqual(latestOffset, this.getScrollOffset())) {
|
|
864
940
|
this.scrollToIndex(index, { align, behavior })
|
|
865
941
|
}
|
|
866
942
|
} else {
|
|
@@ -879,7 +955,7 @@ export class Virtualizer<
|
|
|
879
955
|
)
|
|
880
956
|
}
|
|
881
957
|
|
|
882
|
-
this._scrollToOffset(this.
|
|
958
|
+
this._scrollToOffset(this.getScrollOffset() + delta, {
|
|
883
959
|
adjustments: undefined,
|
|
884
960
|
behavior,
|
|
885
961
|
})
|
package/src/utils.ts
CHANGED
|
@@ -78,10 +78,14 @@ export function notUndefined<T>(value: T | undefined, msg?: string): T {
|
|
|
78
78
|
|
|
79
79
|
export const approxEqual = (a: number, b: number) => Math.abs(a - b) < 1
|
|
80
80
|
|
|
81
|
-
export const debounce = (
|
|
82
|
-
|
|
81
|
+
export const debounce = (
|
|
82
|
+
targetWindow: Window & typeof globalThis,
|
|
83
|
+
fn: Function,
|
|
84
|
+
ms: number,
|
|
85
|
+
) => {
|
|
86
|
+
let timeoutId: number
|
|
83
87
|
return function (this: any, ...args: any[]) {
|
|
84
|
-
clearTimeout(timeoutId)
|
|
85
|
-
timeoutId = setTimeout(() => fn.apply(this, args), ms)
|
|
88
|
+
targetWindow.clearTimeout(timeoutId)
|
|
89
|
+
timeoutId = targetWindow.setTimeout(() => fn.apply(this, args), ms)
|
|
86
90
|
}
|
|
87
91
|
}
|