2022-04-15 14:24:30 +00:00
|
|
|
import { defineAsyncComponent, ref } from 'vue'
|
|
|
|
|
2022-06-10 10:47:46 +00:00
|
|
|
export const useInfiniteScroll = (loadMore: Closure) => {
|
2022-05-12 09:29:55 +00:00
|
|
|
const ToTopButton = defineAsyncComponent(() => import('@/components/ui/BtnScrollToTop.vue'))
|
2022-04-15 14:24:30 +00:00
|
|
|
|
2022-04-21 21:51:17 +00:00
|
|
|
const scroller = ref<HTMLElement>()
|
2022-04-15 14:24:30 +00:00
|
|
|
|
2022-04-21 21:51:17 +00:00
|
|
|
const scrolling = ({ target }: { target: HTMLElement }) => {
|
2022-04-15 14:24:30 +00:00
|
|
|
// Here we check if the user has scrolled to the end of the wrapper (or 32px to the end).
|
|
|
|
// If that's true, load more items.
|
|
|
|
if (target.scrollTop + target.clientHeight >= target.scrollHeight - 32) {
|
2022-06-10 10:47:46 +00:00
|
|
|
loadMore()
|
2022-04-15 14:24:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-10 10:47:46 +00:00
|
|
|
let tries = 0
|
|
|
|
const MAX_TRIES = 5
|
|
|
|
|
|
|
|
const makeScrollable = async () => {
|
2022-05-16 07:34:18 +00:00
|
|
|
const container = scroller.value
|
|
|
|
|
|
|
|
if (!container) {
|
2022-06-10 10:47:46 +00:00
|
|
|
window.setTimeout(() => makeScrollable(), 200)
|
2022-05-16 07:34:18 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2022-06-10 10:47:46 +00:00
|
|
|
if (container.scrollHeight <= container.clientHeight && tries < MAX_TRIES) {
|
|
|
|
tries++
|
|
|
|
await loadMore()
|
|
|
|
window.setTimeout(() => makeScrollable(), 200)
|
2022-04-15 14:24:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
ToTopButton,
|
2022-04-15 17:00:08 +00:00
|
|
|
scroller,
|
2022-04-15 14:24:30 +00:00
|
|
|
scrolling,
|
|
|
|
makeScrollable
|
|
|
|
}
|
|
|
|
}
|