78 lines
1.9 KiB
TypeScript
78 lines
1.9 KiB
TypeScript
import { useEffect } from 'react';
|
|
// eslint-disable-next-line no-unused-vars
|
|
type Callback = (entry: IntersectionObserverEntry) => void;
|
|
|
|
class IntersectionObserverManager {
|
|
private observer: IntersectionObserver;
|
|
private callbacks: Map<Element, Callback>;
|
|
|
|
// eslint-disable-next-line no-undef
|
|
constructor(options: IntersectionObserverInit) {
|
|
this.callbacks = new Map();
|
|
|
|
this.observer = new IntersectionObserver(this.handleIntersect.bind(this), options);
|
|
}
|
|
|
|
private handleIntersect(entries: IntersectionObserverEntry[]) {
|
|
entries.forEach((entry) => {
|
|
const callback = this.callbacks.get(entry.target);
|
|
if (callback) {
|
|
callback(entry);
|
|
}
|
|
});
|
|
}
|
|
|
|
observe(element: Element, callback: Callback) {
|
|
if (element && callback) {
|
|
this.callbacks.set(element, callback);
|
|
this.observer.observe(element);
|
|
}
|
|
}
|
|
|
|
unobserve(element: Element) {
|
|
if (element) {
|
|
this.callbacks.delete(element);
|
|
this.observer.unobserve(element);
|
|
}
|
|
}
|
|
|
|
disconnect() {
|
|
this.observer.disconnect();
|
|
this.callbacks.clear();
|
|
}
|
|
}
|
|
|
|
let manager: IntersectionObserverManager | null = null;
|
|
|
|
// eslint-disable-next-line no-undef
|
|
const getObserverManager = (options: IntersectionObserverInit) => {
|
|
if (!manager) {
|
|
manager = new IntersectionObserverManager(options);
|
|
}
|
|
return manager;
|
|
};
|
|
|
|
export const useSharedIntersectionObserver = (
|
|
// eslint-disable-next-line no-undef
|
|
options: IntersectionObserverInit,
|
|
) => {
|
|
useEffect(() => {
|
|
return () => {
|
|
// Cleanup logic if needed
|
|
// For example, disconnect the observer when the component unmounts entirely
|
|
// This depends on your application's lifecycle
|
|
};
|
|
}, []);
|
|
|
|
if (typeof window === 'undefined') {
|
|
// Return a dummy manager for SSR
|
|
return {
|
|
observe: () => {},
|
|
unobserve: () => {},
|
|
disconnect: () => {},
|
|
} as unknown as IntersectionObserverManager;
|
|
}
|
|
|
|
return getObserverManager(options);
|
|
};
|