rails 中的无限滚动运行次数过多

Infinite scroll in rails runs too many times

正在尝试按照 this tutorial 在 rails 中创建带有刺激的无限滚动。 这是我的观点:

<div data-controller="feed" data-action="scroll@window->feed#scroll" >
  <div data-feed-target="entries">
    <%= render(partial: "feed_posts")%>
  </div>
  <div data-feed-target="pagination"  hidden>
    <%== pagy_nav(@pagy)%>
  </div>
</div>

我的rails控制器:

  def feed 
    @new_post = Post.new
    @pagy, @posts = pagy(Post.where(user_id: current_user.all_following.pluck(:id)).or(Post.where(user_id: current_user.id)).order(created_at: :DESC), items: 5)
    respond_to do |format|
      format.html
      format.json{
        render json:{entries: render_to_string(partial: "feed_posts", formats: [:html]), pagination: view_context.pagy_nav(@pagy)}
      }
    end
  end

最后是我的 js 控制器:

export default class extends Controller {
    static targets = ["entries","pagination"]
    scroll(){
        let next_page = this.paginationTarget.querySelector("a[rel ='next']")
        if(next_page == null ){ return }
        let url = next_page.href
        var body = document.body,
            html = document.documentElement        
        var height = Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight)
        if(window.pageYOffset >= height - window.innerHeight - 100){

            console.log("loading")
            this.loadMore(url)
        }
    }
    loadMore(url){
        Rails.ajax({
            type: 'Get',
            url: url,
            dataType: 'json',
            success: (data) => {
                console.log(data)
                this.entriesTarget.insertAdjacentHTML('beforeend', data.entries);
                this.paginationTarget.innerHTML = data.pagination
            } 
        })
    }
}`

负责查明页面底部是否每次被点击 运行s 不同次数并向视图添加过多结果的代码。

我怎样才能做到 运行 一次,或者让它检查是否添加了 html,之前是否添加过..或者这可能不是一个好主意。

这个技巧叫做Throttle:保证函数定期执行,每X毫秒只执行一次。

查看有关 CSS-TRICKS - Debouncing and Throttling Explained Through Examples

的详细信息

通过刺激使用油门的简单方法是使用 lodash

中的 _throttle 函数
_.throttle(func, [wait=0], [options={}])

查看 Debounce and throttle in Stimulus, _.throttle inside a controller

上的用例

您正在使用的教程源 GoRails 有一个名为 Throttling Infinite Scroll Events in Javascript. If you are not a Pro member of that site, you will not be able to see the video, but there is a link to the source code on GitHub 的后续片段,可免费获取。它提供以下更新 infinite_scroll_container.js

import { Controller } from "stimulus"

export default class extends Controller {
  static targets = ["entries", "pagination"]

  scroll() {
    let next_page = this.paginationTarget.querySelector("a[rel='next']")
    if (next_page == null) { return }

    let url = next_page.href

    var body = document.body,
      html = document.documentElement

    var height = Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight)

    if (window.pageYOffset >= height - window.innerHeight) {
      this.loadMore(url)
    }
  }

  loadMore(url) {
    if (this.loading) { return }
    this.loading = true

    Rails.ajax({
      type: 'GET',
      url: url,
      dataType: 'json',
      success: (data) => {
        this.entriesTarget.insertAdjacentHTML('beforeend', data.entries)
        this.paginationTarget.innerHTML = data.pagination
        this.loading = false
      }
    })
  }
}