How can I implement an infinite scroll in liveview?

I intend to implement an infinite scroll for displaying data. Initially I imagined using the addEventListener’scroll 'event itself with phx-change, to monitor changes, and as soon as the scroll happens, an event is sent to the server and returning an additional data block. But I’m a little confused on how I can make this flow, does anyone have a tip ?

and the js hook:

let Hooks = {}

let scrollAt = () => {
  let scrollTop = document.documentElement.scrollTop || document.body.scrollTop
  let scrollHeight = document.documentElement.scrollHeight || document.body.scrollHeight
  let clientHeight = document.documentElement.clientHeight

  return scrollTop / (scrollHeight - clientHeight) * 100
}

Hooks.InfiniteScroll = {
  page() { return this.el.dataset.page },
  mounted(){
    this.pending = this.page()
    window.addEventListener("scroll", e => {
      if(this.pending == this.page() && scrollAt() > 90){
        this.pending = this.page() + 1
        this.pushEvent("load-more", {})
      }
    })
  },
  reconnected(){ this.pending = this.page() },
  updated(){ this.pending = this.page() }
}

let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content")
let liveSocket = new LiveSocket("/live", Socket, {hooks: Hooks, params: {_csrf_token: csrfToken}})
18 Likes

Thank you so much @chrismccord, seeing this flow, I managed to apply it to my project. You are helping me a lot to understand some specific processes to use in LiveView :heart:

2 Likes

I’m trying to make the infinite scroll works both ways, ie up and down. The use case is for displaying a calendar, much like iCal on Mac where you can scroll infinitely either in the past or in the future. Any idea how this could be achieved?