diff --git a/docs/api/virtualizer.md b/docs/api/virtualizer.md index ffa51478..6e23dc13 100644 --- a/docs/api/virtualizer.md +++ b/docs/api/virtualizer.md @@ -240,6 +240,16 @@ This option allows you to specify the duration to wait after the last scroll eve The implementation of this option is driven by the need for a reliable mechanism to handle scrolling behavior across different browsers. Until all browsers uniformly support the scrollEnd event. +### `useScrollendEvent` + +```tsx +useScrollendEvent: boolean +``` + +This option allows you to switch to use debounced fallback to reset the isScrolling instance property after `isScrollingResetDelay` milliseconds. The default value is `true`. + +The implementation of this option is driven by the need for a reliable mechanism to handle scrolling behavior across different browsers. Until all browsers uniformly support the scrollEnd event. + ### `isRtl` ```tsx diff --git a/packages/virtual-core/src/index.ts b/packages/virtual-core/src/index.ts index 2b3d4ff1..c66c8c92 100644 --- a/packages/virtual-core/src/index.ts +++ b/packages/virtual-core/src/index.ts @@ -130,9 +130,11 @@ export const observeWindowRect = ( const supportsScrollend = typeof window == 'undefined' ? true : 'onscrollend' in window +type ObserveOffsetCallBack = (offset: number, isScrolling: boolean) => void + export const observeElementOffset = ( instance: Virtualizer, - cb: (offset: number, isScrolling: boolean) => void, + cb: ObserveOffsetCallBack, ) => { const element = instance.scrollElement if (!element) { @@ -144,15 +146,16 @@ export const observeElementOffset = ( } let offset = 0 - const fallback = supportsScrollend - ? () => undefined - : debounce( - targetWindow, - () => { - cb(offset, false) - }, - instance.options.isScrollingResetDelay, - ) + const fallback = + instance.options.useScrollendEvent && supportsScrollend + ? () => undefined + : debounce( + targetWindow, + () => { + cb(offset, false) + }, + instance.options.isScrollingResetDelay, + ) const createHandler = (isScrolling: boolean) => () => { const { horizontal, isRtl } = instance.options @@ -177,7 +180,7 @@ export const observeElementOffset = ( export const observeWindowOffset = ( instance: Virtualizer, - cb: (offset: number, isScrolling: boolean) => void, + cb: ObserveOffsetCallBack, ) => { const element = instance.scrollElement if (!element) { @@ -189,15 +192,16 @@ export const observeWindowOffset = ( } let offset = 0 - const fallback = supportsScrollend - ? () => undefined - : debounce( - targetWindow, - () => { - cb(offset, false) - }, - instance.options.isScrollingResetDelay, - ) + const fallback = + instance.options.useScrollendEvent && supportsScrollend + ? () => undefined + : debounce( + targetWindow, + () => { + cb(offset, false) + }, + instance.options.isScrollingResetDelay, + ) const createHandler = (isScrolling: boolean) => () => { offset = element[instance.options.horizontal ? 'scrollX' : 'scrollY'] @@ -291,9 +295,8 @@ export interface VirtualizerOptions< ) => void | (() => void) observeElementOffset: ( instance: Virtualizer, - cb: (offset: number, isScrolling: boolean) => void, + cb: ObserveOffsetCallBack, ) => void | (() => void) - // Optional debug?: boolean initialRect?: Rect @@ -321,6 +324,7 @@ export interface VirtualizerOptions< initialMeasurementsCache?: Array lanes?: number isScrollingResetDelay?: number + useScrollendEvent?: boolean enabled?: boolean isRtl?: boolean } @@ -412,6 +416,7 @@ export class Virtualizer< isScrollingResetDelay: 150, enabled: true, isRtl: false, + useScrollendEvent: true, ...opts, } }