Browse Source
Reviewed-on: https://gitea.anomalistdesign.com/trent_larson/kick-starter-for-time-pwa/pulls/17pull/19/head
anomalist
2 years ago
2 changed files with 82 additions and 6 deletions
@ -0,0 +1,42 @@ |
|||
<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; |
|||
|
|||
mounted() { |
|||
const options = { |
|||
root: this.$refs.scrollContainer as HTMLElement, |
|||
rootMargin: `0px 0px ${this.distance}px 0px`, |
|||
threshold: 1.0, |
|||
}; |
|||
this.observer = new IntersectionObserver(this.handleIntersection, options); |
|||
this.observer.observe(this.$refs.sentinel as HTMLElement); |
|||
} |
|||
|
|||
beforeUnmount() { |
|||
this.observer.disconnect(); |
|||
} |
|||
@Emit("reached-bottom") |
|||
handleIntersection(entries: IntersectionObserverEntry[]) { |
|||
const entry = entries[0]; |
|||
if (entry.isIntersecting) { |
|||
return true; |
|||
} |
|||
return false; |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<!-- Add "scoped" attribute to limit CSS to this component only --> |
|||
<style scoped></style> |
Loading…
Reference in new issue