Add custom useInfiniteScroll
Update haditha
This commit is contained in:
parent
9b776634a6
commit
8cc66757a9
|
@ -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
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
BIN
public/img/haditha/search-show-header.png
Normal file
BIN
public/img/haditha/search-show-header.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 73 KiB |
|
@ -1 +1 @@
|
|||
Subproject commit be9e992c68be3240d197244ff87e5ae910dc88c1
|
||||
Subproject commit 1df5c5d35659e965e51faf69d32a525534421d15
|
Loading…
Reference in New Issue
Block a user