39 lines
1.0 KiB
TypeScript
39 lines
1.0 KiB
TypeScript
import { onMounted, onBeforeUnmount, nextTick } from 'vue';
|
|
|
|
/**
|
|
* useIntersectionObserver
|
|
*
|
|
* @param selector - CSS selector for elements to observe
|
|
* @param callback - called when intersection changes
|
|
* @param options - IntersectionObserver options
|
|
*/
|
|
export const useIntersectionObserver = (
|
|
selector: string,
|
|
callback: IntersectionObserverCallback,
|
|
options: IntersectionObserverInit = {}
|
|
) => {
|
|
let observer: IntersectionObserver | null = null;
|
|
|
|
const defaultOptions: IntersectionObserverInit = {
|
|
threshold: 0.3,
|
|
rootMargin: '0px 0px -50px 0px',
|
|
};
|
|
|
|
onMounted(async () => {
|
|
await nextTick(); // wait for DOM to render
|
|
|
|
const elements = document.querySelectorAll(selector);
|
|
if (!elements.length) return;
|
|
|
|
observer = new IntersectionObserver(callback, { ...defaultOptions, ...options });
|
|
elements.forEach(el => observer!.observe(el));
|
|
});
|
|
|
|
onBeforeUnmount(() => {
|
|
if (observer) {
|
|
observer.disconnect();
|
|
observer = null;
|
|
}
|
|
});
|
|
};
|