You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

55 lines
1.3 KiB

<template>
<div ref="scrollContainer">
<slot />
<div ref="sentinel" style="height: 1px"></div>
</div>
</template>
<script lang="ts">
import { Component, Emit, Prop, Vue } from "vue-facing-decorator";
@Component
export default class InfiniteScroll extends Vue {
@Prop({ default: 100 })
readonly distance!: number;
private observer!: IntersectionObserver;
private isInitialized = false;
mounted() {
this.$nextTick(() => {
this.isInitialized = true;
console.log("onMounted");
const options = {
root: this.$refs.scrollContainer as HTMLElement,
rootMargin: `0px 0px ${this.distance}px 0px`,
threshold: 1.0,
};
this.observer = new IntersectionObserver(
(entries) => this.handleIntersection(entries),
options
);
this.observer.observe(this.$refs.sentinel as HTMLElement);
});
}
beforeUnmount() {
this.observer.disconnect();
}
@Emit("reached-bottom")
handleIntersection(entries: IntersectionObserverEntry[]) {
console.log("handleIntersection");
if (!this.isInitialized) {
return false;
}
const entry = entries[0];
if (entry.isIntersecting && entry.intersectionRatio > 0) {
return true;
}
return false;
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped></style>