We can't find the internet
Attempting to reconnect
Something went wrong!
Hang in there while we get back on track
Impelementing Infinite Scroll in Phoenix
Deankinyua
Infinite scroll is a listing-page design approach seen a lot on widely used apps such as TikTok and Instagram to keep the user engaged, loading additional content as the user scrolls down the page. One of the benefits of infinite scroll is that it reduces interruptions to the user. Yes, even clicking a next button every time could trigger a user to leave your website.
Implementing infinite scroll can become challenging. How do we know we have reached the bottom of the page? We need to know that so as to load more content. Lucky for you, you’ve come to the right place. I’ll be explaining how you can make use of the Intersection Observer API and attach a hook to the bottom of the page which will help detect if the user has reached the bottom.The Intersection Observer works on the basis of a simple mechanism: it observes one or more DOM elements and notifies you when the visibility status of these elements changes.
The first thing you need to do is to place a target element at the bottom of the page :
<div id="infinite-scroll-marker" phx-hook="InfiniteScroll" data-page={@page}></div>
When initializing an observer, a callback function will be specified. This callback is invoked when the observer is first initialized and when an entry is intersecting. If an entry is intersecting that means it is visible on the page. In a LiveView hook, you do the initialization in the mounted callback. The intersection Observer takes a couple of options. Root is target element’s closest scrollable ancestor or if the target element isn’t a descendant of a scrollable element, the device’s viewport. If RootMargin is 100px, the event will fire when the target element is 100px from being visible.
mounted() {
this.pending = this.page()
this.observer = new IntersectionObserver(
(entries) => this.loadMore(entries),
{
root: null, // window by default
rootMargin: '400px',
threshold: 0.1,
}
)
this.observer.observe(this.el)
},
If the element is intersecting, we will increase page by 1 and send this to our LiveView as an event and then load more elements there. This is the full code :
let InfiniteScrollHooks = {}
InfiniteScrollHooks.InfiniteScroll = {
page() {
return this.el.dataset.page
},
loadMore(entries) {
const target = entries[0]
if (target.isIntersecting && this.pending == this.page()) {
this.pending = this.page() + 1
this.pushEvent('load-more', {})
}
},
mounted() {
this.pending = this.page()
this.observer = new IntersectionObserver(
(entries) => this.loadMore(entries),
{
root: null, // window by default
rootMargin: '400px',
threshold: 0.1,
}
)
this.observer.observe(this.el)
},
destroyed() {
this.observer.unobserve(this.el)
},
updated() {
this.pending = this.page()
},
}
export default InfiniteScrollHooks
copied to clipboard