UNPKG

tiny-essentials

Version:

Collection of small, essential scripts designed to be used across various projects. These simple utilities are crafted for speed, ease of use, and versatility.

645 lines 26 kB
export default TinySmartScroller; /** * Represents the dimensions of a DOM element. */ export type NodeSizes = { /** * - The height of the element in pixels. */ height: number; /** * - The width of the element in pixels. */ width: number; }; /** * A callback function that receives node size change data and optionally returns a modified NodeSizes object. */ export type NodeSizesEvent = (elem: Element, sizes: { old: NodeSizes; now: NodeSizes; }, elemAmount: { old: number; now: number; }) => NodeSizes | undefined; /** * A generic scroll-related event listener callback function. */ export type ScrollListenersFunc = (payload: any) => void; /** * Represents the dimensions of a DOM element. * * @typedef {Object} NodeSizes * @property {number} height - The height of the element in pixels. * @property {number} width - The width of the element in pixels. */ /** * A callback function that receives node size change data and optionally returns a modified NodeSizes object. * * @callback NodeSizesEvent * @param {Element} elem - The DOM element whose size is being tracked. * @param {{ old: NodeSizes, now: NodeSizes }} sizes - The old and new size measurements of the element. * @param {{ old: number, now: number }} elemAmount - The number of matching elements before and after the update. * @returns {NodeSizes|undefined} A modified NodeSizes object to override the default measurement, or undefined to use the original. */ /** * A generic scroll-related event listener callback function. * * @callback ScrollListenersFunc * @param {any} payload - The data payload passed when the scroll event is triggered. The type may vary depending on the event. * @returns {void} */ /** * TinySmartScroller is a utility class designed to enhance and manage scroll behaviors within containers or the window. * * It enables advanced scroll monitoring, auto-scrolling to bottom, preserving scroll position during DOM changes, * and detecting visibility changes of elements. This is particularly useful for dynamic UIs like chat applications, * feed viewers, or live content containers. * * Features: * - Detects when the scroll reaches the top, bottom, or custom boundaries * - Supports automatic scrolling to the bottom unless the user scrolls away * - Observes DOM mutations and resizes, and adapts scroll position accordingly * - Emits scroll-related events such as 'onScrollBoundary', 'onAutoScroll', and 'onScrollPause' * - Includes customizable scroll correction filters for layout shift mitigation * - Handles media element load events (e.g. `<img>`, `<iframe>`, `<video>`) to prevent sudden scroll jumps * * This class is **not framework-dependent** and works with vanilla DOM elements and the window object. */ declare class TinySmartScroller { static Utils: { TinyHtml: typeof TinyHtml; getElsRelativeCenterOffset(rect1: ObjRect, rect2: ObjRect): { x: number; y: number; }; getElsCollDirDepth(rect1: ObjRect, rect2: ObjRect): { inDir: Dirs | null; dirX: Dirs | null; dirY: Dirs | null; depthX: number; depthY: number; }; getElsCollDetails(rect1: ObjRect, rect2: ObjRect): { depth: CollData; dirs: CollDirs; isNeg: NegCollDirs; }; areElsCollTop: (rect1: ObjRect, rect2: ObjRect) => boolean; areElsCollBottom: (rect1: ObjRect, rect2: ObjRect) => boolean; areElsCollLeft: (rect1: ObjRect, rect2: ObjRect) => boolean; areElsCollRight: (////////////////////////////////////////////////////////////// /** * Adds a event listener. * * @param {string|string[]} event - Event name, such as 'onScrollBoundary' or 'onAutoScroll'. * @param {ScrollListenersFunc} handler - Callback function to be called when event fires. */ rect1: ObjRect /** * Adds a event listener. * * @param {string|string[]} event - Event name, such as 'onScrollBoundary' or 'onAutoScroll'. * @param {ScrollListenersFunc} handler - Callback function to be called when event fires. */ , //////////////////////////////////////////////////////// /** * Adds a event listener. * * @param {string|string[]} event - Event name, such as 'onScrollBoundary' or 'onAutoScroll'. * @param {ScrollListenersFunc} handler - Callback function to be called when event fires. */ rect2: ObjRect /** * Adds a event listener. * * @param {string|string[]} event - Event name, such as 'onScrollBoundary' or 'onAutoScroll'. * @param {ScrollListenersFunc} handler - Callback function to be called when event fires. */ ) => boolean; areElsCollPerfTop: (rect1: ObjRect, rect2: ObjRect) => boolean; areElsCollPerfBottom: (rect1: ObjRect, rect2: ObjRect) => boolean; areElsCollPerfLeft: (rect1: ObjRect, rect2: ObjRect) => boolean; areElsCollPerfRight: (rect1: ObjRect, rect2: ObjRect) => boolean; areElsColliding: (//////////////////////////////////////////////////////// /** * Removes a previously registered event listener. * * @param {string|string[]} event - The name of the event to remove the handler from. * @param {ScrollListenersFunc} handler - The specific callback function to remove. */ rect1: ObjRect /** * Removes a previously registered event listener. * * @param {string|string[]} event - The name of the event to remove the handler from. * @param {ScrollListenersFunc} handler - The specific callback function to remove. */ , ////////////////////////////////////////////////// /** * Removes a previously registered event listener. * * @param {string|string[]} event - The name of the event to remove the handler from. * @param {ScrollListenersFunc} handler - The specific callback function to remove. */ rect2: ObjRect /** * Removes a previously registered event listener. * * @param {string|string[]} event - The name of the event to remove the handler from. * @param {ScrollListenersFunc} handler - The specific callback function to remove. */ ) => boolean; areElsPerfColliding: (rect1: ObjRect, rect2: ObjRect) => boolean; getElsColliding: (rect1: ObjRect, rect2: ObjRect) => string | null; getElsPerfColliding: (rect1: ObjRect, rect2: ObjRect) => "top" | "bottom" | "left" | "right" | null; getElsCollOverlap: (rect1: ObjRect, rect2: ObjRect) => { overlapLeft: number; overlapRight: number; overlapTop: number; overlapBottom: number; }; getElsCollOverlapPos: ({ overlapLeft, overlapRight, overlapTop, overlapBottom, }?: { overlapLeft?: number | undefined; overlapRight?: number | undefined; overlapTop?: number | undefined; overlapBottom?: number | undefined; }) => { dirX: Dirs; dirY: Dirs; }; getRectCenter: (rect: ObjRect) => { x: number; y: number; }; }; /** * Creates a new instance of TinySmartScroller, attaching scroll and resize observers to manage * automatic scroll behaviors, layout shift correction, and visibility tracking. * * @param {Element|Window} target - The scroll container to monitor. Can be an element or `window`. * @param {Object} [options={}] - Optional settings to configure scroll behavior. * @param {number} [options.extraScrollBoundary=0] - Extra margin in pixels to extend scroll boundary detection. * @param {boolean} [options.autoScrollBottom=true] - Whether to auto-scroll to bottom on layout updates. * @param {boolean} [options.observeMutations=true] - Enables MutationObserver to detect DOM changes. * @param {boolean} [options.preserveScrollOnLayoutShift=true] - Prevents scroll jumps when layout changes. * @param {number} [options.debounceTime=100] - Debounce time in milliseconds for scroll events. * @param {string|null} [options.querySelector=null] - Optional CSS selector to filter observed child nodes. * @param {string[]|Set<string>|null} [options.attributeFilter=['class', 'style', 'src', 'data-*', 'height', 'width']] * - Which attributes to observe for changes. */ constructor(target: Element | Window, { extraScrollBoundary, autoScrollBottom, observeMutations, preserveScrollOnLayoutShift, debounceTime, querySelector, attributeFilter, }?: { extraScrollBoundary?: number | undefined; autoScrollBottom?: boolean | undefined; observeMutations?: boolean | undefined; preserveScrollOnLayoutShift?: boolean | undefined; debounceTime?: number | undefined; querySelector?: string | null | undefined; attributeFilter?: string[] | Set<string> | null | undefined; }); /** * Enables or disables throwing an error when the maximum number of listeners is exceeded. * * @param {boolean} shouldThrow - If true, an error will be thrown when the max is exceeded. */ setThrowOnMaxListeners(shouldThrow: boolean): void; /** * Checks whether an error will be thrown when the max listener limit is exceeded. * * @returns {boolean} True if an error will be thrown, false if only a warning is shown. */ getThrowOnMaxListeners(): boolean; /** * Adds a listener to the beginning of the listeners array for the specified event. * * @param {string|string[]} event - Event name. * @param {ScrollListenersFunc} handler - The callback function. */ prependListener(event: string | string[], handler: ScrollListenersFunc): void; /** * Adds a one-time listener to the beginning of the listeners array for the specified event. * * @param {string|string[]} event - Event name. * @param {ScrollListenersFunc} handler - The callback function. * @returns {ScrollListenersFunc[]} - The wrapped handler used internally. */ prependListenerOnce(event: string | string[], handler: ScrollListenersFunc): ScrollListenersFunc[]; /** * Adds a event listener. * * @param {string|string[]} event - Event name, such as 'onScrollBoundary' or 'onAutoScroll'. * @param {ScrollListenersFunc} handler - Callback function to be called when event fires. */ appendListener(event: string | string[], handler: ScrollListenersFunc): void; /** * Registers an event listener that runs only once, then is removed. * * @param {string|string[]} event - Event name, such as 'onScrollBoundary' or 'onAutoScroll'. * @param {ScrollListenersFunc} handler - The callback function to run on event. * @returns {ScrollListenersFunc[]} - The wrapped version of the handler. */ appendListenerOnce(event: string | string[], handler: ScrollListenersFunc): ScrollListenersFunc[]; /** * Adds a event listener. * * @param {string|string[]} event - Event name, such as 'onScrollBoundary' or 'onAutoScroll'. * @param {ScrollListenersFunc} handler - Callback function to be called when event fires. */ on(event: string | string[], handler: ScrollListenersFunc): void; /** * Registers an event listener that runs only once, then is removed. * * @param {string|string[]} event - Event name, such as 'onScrollBoundary' or 'onAutoScroll'. * @param {ScrollListenersFunc} handler - The callback function to run on event. * @returns {ScrollListenersFunc[]} - The wrapped version of the handler. */ once(event: string | string[], handler: ScrollListenersFunc): ScrollListenersFunc[]; /** * Removes a previously registered event listener. * * @param {string|string[]} event - The name of the event to remove the handler from. * @param {ScrollListenersFunc} handler - The specific callback function to remove. */ off(event: string | string[], handler: ScrollListenersFunc): void; /** * Removes all event listeners of a specific type from the element. * * @param {string|string[]} event - The event type to remove (e.g. 'onScrollBoundary'). */ offAll(event: string | string[]): void; /** * Removes all event listeners of all types from the element. */ offAllTypes(): void; /** * Returns the number of listeners for a given event. * * @param {string} event - The name of the event. * @returns {number} Number of listeners for the event. */ listenerCount(event: string): number; /** * Returns a copy of the array of listeners for the specified event. * * @param {string} event - The name of the event. * @returns {ScrollListenersFunc[]} Array of listener functions. */ listeners(event: string): ScrollListenersFunc[]; /** * Returns a copy of the array of listeners for the specified event. * * @param {string} event - The name of the event. * @returns {ScrollListenersFunc[]} Array of listener functions. */ onceListeners(event: string): ScrollListenersFunc[]; /** * Returns a copy of the internal listeners array for the specified event, * including wrapper functions like those used by `.once()`. * @param {string | symbol} event - The event name. * @returns {ScrollListenersFunc[]} An array of raw listener functions. */ allListeners(event: string | symbol): ScrollListenersFunc[]; /** * Returns an array of event names for which there are registered listeners. * * @returns {string[]} Array of registered event names. */ eventNames(): string[]; /** * Emits an event, triggering all registered handlers for that event. * * @param {string} event - The event name to emit. * @param {...any} payload - Optional data to pass to each handler. * @returns {boolean[]} True if any listeners were called, false otherwise. */ emit(event: string, ...payload: any[]): boolean[]; /** * Sets the maximum number of listeners per event before a warning is shown. * * @param {number} n - The maximum number of listeners. */ setMaxListeners(n: number): void; /** * Gets the maximum number of listeners allowed per event. * * @returns {number} The maximum number of listeners. */ getMaxListeners(): number; /** * Returns a size difference callback that only reacts when height changes, filtered by tag name. * * @param {string[]} filter - List of tag names to allow. If empty, all tags are accepted. * @returns {NodeSizesEvent} A function that compares previous and current height, returning height delta. */ getSimpleOnHeight(filter?: string[]): NodeSizesEvent; /** * Adds a height difference callback to the size filter system. * * @param {string[]} filter - List of tag names to allow. * @returns {NodeSizesEvent} The added size difference callback. */ addSimpleOnHeight(filter: string[]): NodeSizesEvent; /** * Returns a list of all currently tracked load tags. * * @returns {string[]} Array of tag names. */ getLoadTags(): string[]; /** * Adds a new tag to the set of load tags. * * @param {string} tag - The tag name to add (e.g., 'IMG'). */ addLoadTag(tag: string): void; /** * Removes a tag from the set of load tags. * * @param {string} tag - The tag name to remove. */ removeLoadTag(tag: string): void; /** * Checks whether a tag is tracked as a load tag. * * @param {string} tag - The tag name to check. * @returns {boolean} True if the tag is being tracked. */ hasLoadTag(tag: string): boolean; /** * Clears the set of load tags. If `addDefault` is true, it will reset to the default tags: 'IMG', 'IFRAME', and 'VIDEO'. * * @param {boolean} [addDefault=false] - Whether to restore the default tags after clearing. * @throws {TypeError} If `addDefault` is not a boolean. */ resetLoadTags(addDefault?: boolean): void; /** * Returns a list of all currently tracked attribute filters. * * @returns {string[]} Array of attribute names. */ getAttributeFilters(): string[]; /** * Adds an attribute to the filter list. * * @param {string} attr - The attribute name to add. */ addAttributeFilter(attr: string): void; /** * Removes an attribute from the filter list. * * @param {string} attr - The attribute name to remove. */ removeAttributeFilter(attr: string): void; /** * Checks whether a specific attribute is being filtered. * * @param {string} attr - The attribute name to check. * @returns {boolean} True if the attribute is being filtered. */ hasAttributeFilter(attr: string): boolean; /** * Clears the set of observed attribute filters. If `addDefault` is true, it will reset to the default attributes: * 'class', 'style', 'src', 'data-*', 'height', and 'width'. * * @param {boolean} [addDefault=false] - Whether to restore the default attribute filters after clearing. * @throws {TypeError} If `addDefault` is not a boolean. */ resetAttributeFilters(addDefault?: boolean): void; /** * Registers a custom node size change handler to the internal size filter set. * * @param {NodeSizesEvent} handler - Function that compares old and new sizes. */ onSize(handler: NodeSizesEvent): void; /** * Unregisters a previously registered size handler from the internal filter set. * * @param {NodeSizesEvent} handler - The handler function to remove. */ offSize(handler: NodeSizesEvent): void; /** * Checks which elements inside the target are currently visible and updates internal maps. * * @returns {Map<Element, { oldIsVisible: boolean; isVisible: boolean }>} Visibility comparison results. */ _scrollDataUpdater(): Map<Element, { oldIsVisible: boolean; isVisible: boolean; }>; /** * Handles scroll events, calculates position-related statuses, and emits appropriate events. */ _onScroll(): void; /** * Attempts to correct the scroll position when layout shifts happen, preserving the user position if needed. * * @param {Element[]} [targets=[]] - List of elements involved in the size change. */ _fixScroll(targets?: Element[]): void; /** * Sets up a MutationObserver to watch for DOM changes and react accordingly to maintain scroll consistency. */ _observeMutations(): void; /** * Adds a ResizeObserver to monitor elements' size changes and trigger layout adjustments. * * @param {NodeListOf<Element>|Element[]|HTMLCollection} elements - Elements to observe. */ _observeResizes(elements: NodeListOf<Element> | Element[] | HTMLCollection): void; /** * Listens for media/content load events (e.g., images, iframes, videos) to trigger scroll updates. * * @param {NodeListOf<Element>|Element} elements - Target element(s) to listen on. */ _listenLoadEvents(elements: NodeListOf<Element> | Element): void; /** * Returns the internal scroll container element being monitored. * * @returns {Element} The DOM element used as the scroll container target. */ get target(): Element; /** * Returns the previous size of a given element, or undefined if not tracked. * * @param {Element} el - The DOM element to query. * @returns {NodeSizes|null} The old size, or undefined. */ getOldSize(el: Element): NodeSizes | null; /** * Returns the current size of a given element, or undefined if not tracked. * * @param {Element} el - The DOM element to query. * @returns {NodeSizes|null} The new size, or undefined. */ getNewSize(el: Element): NodeSizes | null; /** * Returns whether the given element was visible in the last scroll update. * * @param {Element} el - The DOM element to check. * @returns {boolean} True if visible, false if not, or undefined if not tracked. */ wasVisible(el: Element): boolean; /** * Returns whether the given element is currently visible. * * @param {Element} el - The DOM element to check. * @returns {boolean} True if visible, false if not, or undefined if not tracked. */ isVisible(el: Element): boolean; /** * Returns whether the element was visible in the last time-based visibility check. * * @param {Element} el - The DOM element to check. * @returns {boolean} Visibility state from the previous timed check. */ wasTimedVisible(el: Element): boolean; /** * Returns whether the element is currently visible in the time-based check. * * @param {Element} el - The DOM element to check. * @returns {boolean} Visibility state from the current timed check. */ isTimedVisible(el: Element): boolean; /** * Sets the extra scroll boundary margin used when determining if the user is at a "custom" bottom or top. * * @param {number} value - Pixels of additional margin to use. */ setExtraScrollBoundary(value: number): void; /** * Returns the current extra scroll boundary setting. * * @returns {number} */ getExtraScrollBoundary(): number; /** * Returns the last known distance (in pixels) from the bottom of the scroll container. * * @returns {number} */ getLastKnownScrollBottomOffset(): number; /** * Forces the scroll position to move to the very bottom of the target. */ scrollToBottom(): void; /** * Forces the scroll position to move to the very top of the target. */ scrollToTop(): void; /** * Checks if the user is within the defined extra scroll boundary from the bottom. * * @returns {boolean} */ isAtCustomBottom(): boolean; /** * Checks if the user is within the defined extra scroll boundary from the top. * * @returns {boolean} */ isAtCustomTop(): boolean; /** * Returns true if the user is currently scrolled to the bottom of the element. * * @returns {boolean} */ isAtBottom(): boolean; /** * Returns true if the user is currently scrolled to the top of the element. * * @returns {boolean} */ isAtTop(): boolean; /** * Returns true if the user has already passed beyond the bottom boundary at some point. * * @returns {boolean} */ isPastAtBottom(): boolean; /** * Returns true if the user has already passed beyond the top boundary at some point. * * @returns {boolean} */ isPastAtTop(): boolean; /** * Returns true if the user has passed beyond the defined extra scroll boundary from the top at some point. * * @returns {boolean} */ isPastAtCustomTop(): boolean; /** * Returns true if the user has passed beyond the defined extra scroll boundary from the bottom at some point. * * @returns {boolean} */ isPastAtCustomBottom(): boolean; /** * Returns true if automatic scrolling is currently paused. * * @returns {boolean} */ isScrollPaused(): boolean; /** * Returns whether the target is the window object. * * @returns {boolean} True if the scroll target is window, false otherwise. */ isWindow(): boolean; /** * Returns whether the instance has been destroyed. * * @returns {boolean} True if the instance is destroyed, false otherwise. */ isDestroyed(): boolean; /** * Returns whether auto-scroll-to-bottom is enabled. * * @returns {boolean} True if auto-scroll is active, false otherwise. */ getAutoScrollBottom(): boolean; /** * Returns whether MutationObserver is enabled. * * @returns {boolean} True if mutation observation is active, false otherwise. */ getObserveMutations(): boolean; /** * Returns whether layout shift protection is enabled. * * @returns {boolean} True if scroll preservation is active, false otherwise. */ getPreserveScrollOnLayoutShift(): boolean; /** * Returns the debounce delay in milliseconds used for scroll events. * * @returns {number} Debounce delay time. */ getDebounceTime(): number; /** * Returns the current number of matching elements observed inside the scroll target. * * @returns {number} Current count of matching elements. */ getElemAmount(): number; /** * Returns the previous known count of matching elements from the last update. * * @returns {number} Previous count of matching elements. */ getPrevElemAmount(): number; /** * Returns the query selector string used to filter observed elements. * * @returns {string} The CSS selector string, or an empty string if none was provided. */ getQuerySelector(): string; /** * Disconnects all listeners, observers, and clears memory structures. * Once destroyed, this instance should no longer be used. */ destroy(): void; #private; } import TinyHtml from './TinyHtml.mjs'; import * as TinyCollision from '../basics/collision.mjs'; //# sourceMappingURL=TinySmartScroller.d.mts.map