无限滚动在轨道运行太多次



尝试按照本教程创建无限滚动与刺激在轨道。下面是我的视图:

<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>

my rails controller:

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
} 
})
}
}`

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

我怎么能让它运行一次希望或有它检查,看看是否正在添加的html,之前是否添加…或者这可能不是一个好主意。

此技术称为Throttle:保证有规律地执行函数,每X毫秒才执行一次。

查看CSS-TRICKS - debouting and Throttling的详细信息

用lodash

中的_throttle函数来使用节流与刺激的简单方法
_.throttle(func, [wait=0], [options={}])

查看Debounce和throttle在Stimulus, _中的用例。控制器内节流阀

您正在使用的教程的源代码,GoRails,有一个后续章节叫做在Javascript中Throttling Infinite Scroll Events。如果你不是该网站的专业会员,你将无法看到视频,但在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
}
})
}
}

最新更新