continue re-design
This commit is contained in:
@@ -0,0 +1,130 @@
|
||||
export function setTimeoutOnVisible({
|
||||
element,
|
||||
callback,
|
||||
timeout,
|
||||
threshold = 0.01,
|
||||
}: {
|
||||
element?: HTMLElement;
|
||||
callback: () => void;
|
||||
timeout: number;
|
||||
threshold?: number;
|
||||
}) {
|
||||
if (!element) {
|
||||
return;
|
||||
}
|
||||
|
||||
let timeoutId: NodeJS.Timeout | null = null;
|
||||
let finished = false;
|
||||
|
||||
// Check if element is already visible at the beginning
|
||||
const rect = element.getBoundingClientRect();
|
||||
const isVisible = rect.top < window.innerHeight && rect.bottom > 0;
|
||||
|
||||
const setupTimeout = () => {
|
||||
if (finished) return;
|
||||
|
||||
timeoutId = setTimeout(() => {
|
||||
if (finished) return;
|
||||
|
||||
callback();
|
||||
timeoutId = null;
|
||||
finished = true;
|
||||
}, timeout);
|
||||
};
|
||||
|
||||
if (isVisible && !timeoutId) setupTimeout();
|
||||
|
||||
const observer = new IntersectionObserver(
|
||||
(entries) => {
|
||||
entries.forEach((entry) => {
|
||||
if (entry.isIntersecting) {
|
||||
// Element is visible, start the timeout
|
||||
if (!timeoutId) {
|
||||
setupTimeout();
|
||||
observer.disconnect();
|
||||
}
|
||||
} else {
|
||||
// Element is no longer visible, clear the timeout
|
||||
if (timeoutId) {
|
||||
clearTimeout(timeoutId);
|
||||
timeoutId = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
{ threshold },
|
||||
);
|
||||
|
||||
observer.observe(element);
|
||||
|
||||
// Return a cleanup function
|
||||
return () => {
|
||||
if (timeoutId) {
|
||||
clearTimeout(timeoutId);
|
||||
}
|
||||
|
||||
observer.disconnect();
|
||||
};
|
||||
}
|
||||
|
||||
export function setIntervalOnVisible({
|
||||
element,
|
||||
callback,
|
||||
interval,
|
||||
threshold = 0.01,
|
||||
}: {
|
||||
element?: HTMLElement | null;
|
||||
callback: () => void;
|
||||
interval: number;
|
||||
threshold?: number;
|
||||
}) {
|
||||
if (!element) {
|
||||
return;
|
||||
}
|
||||
|
||||
let intervalId: NodeJS.Timeout | null = null;
|
||||
|
||||
// Check if element is already visible at the beginning
|
||||
const rect = element.getBoundingClientRect();
|
||||
const isVisible = rect.top < window.innerHeight && rect.bottom > 0;
|
||||
|
||||
const setupInterval = () => {
|
||||
if (!intervalId) {
|
||||
intervalId = setInterval(callback, interval);
|
||||
}
|
||||
};
|
||||
|
||||
const clearIntervalIfExists = () => {
|
||||
if (intervalId) {
|
||||
clearInterval(intervalId);
|
||||
intervalId = null;
|
||||
}
|
||||
};
|
||||
|
||||
if (isVisible) setupInterval();
|
||||
|
||||
const observer = new IntersectionObserver(
|
||||
(entries) => {
|
||||
entries.forEach((entry) => {
|
||||
if (entry.isIntersecting) {
|
||||
// Element is visible, start the interval
|
||||
setupInterval();
|
||||
} else {
|
||||
// Element is no longer visible, clear the interval
|
||||
clearIntervalIfExists();
|
||||
}
|
||||
});
|
||||
},
|
||||
{ threshold },
|
||||
);
|
||||
|
||||
observer.observe(element);
|
||||
|
||||
// Return a cleanup function
|
||||
return () => {
|
||||
clearIntervalIfExists();
|
||||
observer.disconnect();
|
||||
};
|
||||
}
|
||||
|
||||
export default setTimeoutOnVisible;
|
||||
Reference in New Issue
Block a user