Update useInfiniteScroll files

This commit is contained in:
mustafa-rezae 2025-05-19 11:58:03 +03:30
parent b573c61d4e
commit 080a4fee59
4 changed files with 93 additions and 24 deletions

View File

@ -1,18 +1,58 @@
// composables/useInfiniteScroll.ts
import { ref, onMounted, onBeforeUnmount } from "vue";
export default function useInfiniteScroll(
callback: () => void,
elementId: string
callback: () => Promise<void>,
elementId?: string
) {
const route = useRoute();
const isFetching = ref(false);
const infiniteScroll = ref<HTMLElement | null>(null);
const infiniteScroll = ref<HTMLElement | Window | null>(null);
const handleScroll = () => {
if (isFetching.value) return;
const scrollPosition =
infiniteScroll.value.scrollTop + infiniteScroll.value.clientHeight;
const threshold = infiniteScroll.value.scrollHeight - 100;
// Throttle function to limit scroll event frequency
const throttle = (func: (...args: any[]) => void, limit: number) => {
let lastFunc: ReturnType<typeof setTimeout>;
let lastRan: number;
return function (this: any, ...args: any[]) {
const context = this;
if (!lastRan) {
func.apply(context, args);
lastRan = Date.now();
} else {
clearTimeout(lastFunc);
lastFunc = setTimeout(() => {
if (Date.now() - lastRan >= limit) {
func.apply(context, args);
lastRan = Date.now();
}
}, limit - (Date.now() - lastRan));
}
};
};
if (scrollPosition >= threshold) {
const checkScrollPosition = () => {
if (isFetching.value || !infiniteScroll.value) return;
let scrollPosition: number;
let threshold: number;
let clientHeight: number;
let scrollHeight: number;
if (infiniteScroll.value === window) {
scrollPosition = window.scrollY || window.pageYOffset;
clientHeight = document.documentElement.clientHeight;
scrollHeight = document.documentElement.scrollHeight;
} else {
const el = infiniteScroll.value as HTMLElement;
scrollPosition = el.scrollTop;
clientHeight = el.clientHeight;
scrollHeight = el.scrollHeight;
}
threshold = scrollHeight - 100;
const currentPosition = scrollPosition + clientHeight;
if (currentPosition >= threshold) {
isFetching.value = true;
callback().finally(() => {
isFetching.value = false;
@ -20,28 +60,57 @@ export default function useInfiniteScroll(
}
};
// Throttled version of scroll handler
const throttledScrollHandler = throttle(checkScrollPosition, 200);
const handleTouchEnd = () => {
// Add a slight delay to ensure scroll position is updated
setTimeout(handleScroll, 100);
setTimeout(throttledScrollHandler, 100);
};
onMounted(() => {
const targetElement = document.getElementById(elementId);
infiniteScroll.value = targetElement;
console.info(route.name)
if (route.name == "hadithaSearch" || route.name == "hadithaLibrary") {
const targetElement = elementId
? document.getElementById(elementId)
: window;
if (targetElement) {
targetElement.addEventListener("scroll", handleScroll);
targetElement.addEventListener("touchend", handleTouchEnd);
if (!targetElement) {
console.warn(
`Element ${elementId || "window"} not found for infinite scroll`
);
return;
}
infiniteScroll.value = targetElement;
if (targetElement === window) {
window.addEventListener("scroll", throttledScrollHandler);
window.addEventListener("touchend", handleTouchEnd);
} else {
targetElement.addEventListener("scroll", throttledScrollHandler);
targetElement.addEventListener("touchend", handleTouchEnd);
}
}
});
onBeforeUnmount(() => {
const targetElement = document.getElementById(elementId);
infiniteScroll.value = targetElement;
if (route.name == "hadithaSearch" || route.name == "hadithaLibrary") {
if (!infiniteScroll.value) return;
if (targetElement) {
targetElement.removeEventListener("scroll", handleScroll);
targetElement.removeEventListener("touchend", handleTouchEnd);
if (infiniteScroll.value === window) {
window.removeEventListener("scroll", throttledScrollHandler);
window.removeEventListener("touchend", handleTouchEnd);
} else {
(infiniteScroll.value as HTMLElement).removeEventListener(
"scroll",
throttledScrollHandler
);
(infiniteScroll.value as HTMLElement).removeEventListener(
"touchend",
handleTouchEnd
);
}
}
});

@ -1 +1 @@
Subproject commit c3aa6605ff449226a04817f0fb29a4b0f77654bc
Subproject commit e1047621e2b74024de94331d7a1f424e83214440

@ -1 +1 @@
Subproject commit 117dc3e4faed749ac4dbfbf0a41899fe22282c84
Subproject commit f4dbda3abbe6ca4b18fe3e2f452a3684ca13c9ad

@ -1 +1 @@
Subproject commit dce0b4fe6cf7158ac7cb841564e78de33e23d0a3
Subproject commit 1c5b1d47a1a07ba1a567e9f11fd60d5408fde883