50 lines
1.3 KiB
TypeScript
50 lines
1.3 KiB
TypeScript
// composables/useInfiniteScroll.ts
|
|
export default function useInfiniteScroll(
|
|
callback: () => void,
|
|
elementId: string
|
|
) {
|
|
const isFetching = ref(false);
|
|
const infiniteScroll = ref<HTMLElement | null>(null);
|
|
|
|
const handleScroll = () => {
|
|
if (isFetching.value) return;
|
|
const scrollPosition =
|
|
infiniteScroll.value.scrollTop + infiniteScroll.value.clientHeight;
|
|
const threshold = infiniteScroll.value.scrollHeight - 100;
|
|
|
|
if (scrollPosition >= threshold) {
|
|
isFetching.value = true;
|
|
callback().finally(() => {
|
|
isFetching.value = false;
|
|
});
|
|
}
|
|
};
|
|
|
|
const handleTouchEnd = () => {
|
|
// Add a slight delay to ensure scroll position is updated
|
|
setTimeout(handleScroll, 100);
|
|
};
|
|
|
|
onMounted(() => {
|
|
const targetElement = document.getElementById(elementId);
|
|
infiniteScroll.value = targetElement;
|
|
|
|
if (targetElement) {
|
|
targetElement.addEventListener("scroll", handleScroll);
|
|
targetElement.addEventListener("touchend", handleTouchEnd);
|
|
}
|
|
});
|
|
|
|
onBeforeUnmount(() => {
|
|
const targetElement = document.getElementById(elementId);
|
|
infiniteScroll.value = targetElement;
|
|
|
|
if (targetElement) {
|
|
targetElement.removeEventListener("scroll", handleScroll);
|
|
targetElement.removeEventListener("touchend", handleTouchEnd);
|
|
}
|
|
});
|
|
|
|
return { isFetching };
|
|
}
|