import Notifications from './notification'; export interface IOptions { root?: HTMLElement; rootMargin?: string; threshold?: number | number[]; [key: string]: any; } export default class IntersectionObserverAdmin extends Notifications { private elementRegistry; constructor(); /** * Adds element to observe via IntersectionObserver and stores element + relevant callbacks and observer options in static * administrator for lookup in the future * * @method observe * @param {HTMLElement | Window} element * @param {Object} options * @public */ observe(element: HTMLElement, options?: IOptions): void; /** * Unobserve target element and remove element from static admin * * @method unobserve * @param {HTMLElement|Window} target * @param {Object} options * @public */ unobserve(target: HTMLElement, options: IOptions): void; /** * register event to handle when intersection observer detects enter * * @method addEnterCallback * @public */ addEnterCallback(element: HTMLElement | Window, callback: (data?: any) => void): void; /** * register event to handle when intersection observer detects exit * * @method addExitCallback * @public */ addExitCallback(element: HTMLElement | Window, callback: (data?: any) => void): void; /** * retrieve registered callback and call with data * * @method dispatchEnterCallback * @public */ dispatchEnterCallback(element: HTMLElement | Window, entry: any): void; /** * retrieve registered callback and call with data on exit * * @method dispatchExitCallback * @public */ dispatchExitCallback(element: HTMLElement | Window, entry: any): void; /** * cleanup data structures and unobserve elements * * @method destroy * @public */ destroy(): void; /** * cleanup removes provided elements from both registries * * @method removeElement * @public * */ removeElement(element: HTMLElement | Window): void; /** * checks whether element exists in either registry * * @method elementExists * @public * */ elementExists(element: HTMLElement | Window): boolean; /** * use function composition to curry options * * @method setupOnIntersection * @param {Object} options */ protected setupOnIntersection(options: IOptions): Function; protected setupObserver(element: HTMLElement, options: IOptions): void; private newObserver; /** * IntersectionObserver callback when element is intersecting viewport * either when `isIntersecting` changes or `intersectionRadio` crosses on of the * configured `threshold`s. * Exit callback occurs eagerly (when element is initially out of scope) * See https://stackoverflow.com/questions/53214116/intersectionobserver-callback-firing-immediately-on-page-load/53385264#53385264 * * @method onIntersection * @param {Object} options * @param {Array} ioEntries * @private */ private onIntersection; /** * { root: { stringifiedOptions: { observer, elements: []...] } } * @method findRootFromRegistry * @param {HTMLElement|Window} root * @private * @return {Object} of elements that share same root */ private findRootFromRegistry; /** * We don't care about options key order because we already added * to the static administrator * * @method findMatchingRootEntry * @param {Object} options * @return {Object} entry with elements and other options */ private findMatchingRootEntry; /** * Determine if existing elements for a given root based on passed in options * regardless of sort order of keys * * @method determineMatchingElements * @param {Object} options * @param {Object} potentialRootMatch e.g. { stringifiedOptions: { elements: [], ... }, stringifiedOptions: { elements: [], ... }} * @private * @return {Object} containing array of elements and other meta */ private determineMatchingElements; /** * recursive method to test primitive string, number, null, etc and complex * object equality. * * @method areOptionsSame * @param {any} a * @param {any} b * @private * @return {boolean} */ private areOptionsSame; /** * Stringify options for use as a key. * Excludes options.root so that the resulting key is stable * * @param {Object} options * @private * @return {String} */ private stringifyOptions; private clearRootEntry; private clearDefaultRoot; }