【问题标题】:Ajax GET is getting called twice (in Endless Scroll)Ajax GET 被调用两次(在 Endless Scroll 中)
【发布时间】:2016-01-24 05:35:48
【问题描述】:

我有一个由 ajax 和 jQuery 制作的无限滚动。它使用控制器(Laravel5)中分页的项目,使用ajax获取它。

一切正常,但我有一个问题。当我点击页面底部时,它会进行两次 ajax 调用。我怀疑这是因为setInterval,因为当我更改时间时,它会影响那部分。

// Creates the pagination pages [<[1]2]3]>]
{!! $boxes->render() !!}

// Html
        <input type="hidden" id="page" value="1" />
        <input type="hidden" id="max_page" value="{{{ $boxes-id }}}" />
        <div id="end_of_page" class="center">
            <hr/>
            <span>End of the feed.</span>

<script>
  $(document).ready(function() {

    var didScroll = false;

       $(window).scroll(function() { //watches scroll of the window
             didScroll = true;
       });


       //Sets an interval so your window.scroll event doesn't fire constantly. This waits for the user to stop scrolling for not even a second and then fires the pageCountUpdate function (and then the getPost function)
    setInterval(function() {
        if (didScroll){
           didScroll = false;
           if(($(document).height()-$(window).height())-$(window).scrollTop() < 10){
                  pageCountUpdate();
            }
        }
    }, 250);  

例如,当我将 250 更改为 5000 时,它会给出一个中间时间,但这不是我想要的。我想在触底后只进行一次调用,也许用布尔变量禁用它,然后在新元素加载后重新激活它(在 ajax 成功状态下),但我无法弄清楚将阻塞变量。

//Continuing

    function pageCountUpdate(){
          var page = parseInt($('#page').val());
          var max_page = parseInt($('#max_page').val());

          if(page < max_page){
              $('#page').val(page+1);
              getPosts();
              $('#end_of_page').hide();
          } else {
              $('#end_of_page').fadeIn();
          }
      }

    function getPosts(){
        var data = { "page": $('#page').val() }
        $.ajax({
                type: "POST",

                //Classic ajax call

                beforeSend: function(){
                ..}
                complete: function(){
                ..}
                success: function(){
                ..}    
        });
    }

 } 
});

更新:关于cmets中提到的John Resig的例子,我需要使用var outerPane = $details.find(".details-pane-outer"), didScroll = false;。我认为没有这部分会造成我的问题,但我无法弄清楚使用find() 方法在哪里选择。

【问题讨论】:

  • 使用间隔似乎不是消除事件的好方法?
  • 实现这一目标的最佳方法是什么?您建议使用什么来代替间隔?
  • 虽然我确信他不是唯一倡导这种模式的人,但 John Resig 在this post 中推荐它以简化通话。
  • 需要在哪里设置outerPane? var outerPane = $details.find(".details-pane-outer"),。我需要用$details.find(".details-pane-outer") 选择什么?我试过var outerPane = $('#content'), 但没有改变任何东西
  • @Phix - 那么它可能没问题。我以前从未见过它这样做过,并且总是有一个每秒运行 4 次的函数,这似乎不是一个好主意。我会在事件处理程序中使用超时,但这只是我。

标签: javascript jquery html ajax pagination


【解决方案1】:

除了你奇怪的 setinterval 结构(只需将代码移动到滚动事件中,没有间隔)。

似乎在页面底部的最后 10 个像素内多次调用了滚动事件。因此,当滚动到底部时,距底部 9 像素处,会触发该事件以加载更多帖子。但即使在加载新帖子之前,同时您滚动一点,再次触发滚动事件。这会使您的帖子加载两次甚至两次以上。

要解决此问题,您可以添加一个简单的布尔开关,以确保帖子在已加载时不会再次加载。比如:

var loading=false;
function onReachScrollLimit(){
    if(loading){return;}
    loading=true;
    load_new_posts();
}
function load_new_posts(){
    //insert the posts
    loading=false;
}

【讨论】:

  • 感谢您的回答。您的意思是将 setInterval 移动到$(window).scroll(function() { 吗?而且,我是否也应该将pageCountUpdate(); 放在load_new_posts() 中? .我很困惑将它适应我的代码。对不起,我是 jquery 的新手。
  • 啊,我以为你理解了你发布的代码。首先,尝试了解正在发生的一切,它将帮助您学习 javascript。 setInterval 是一个每 X 毫秒运行一次代码的函数。因此,您总结的代码执行以下操作:每次滚动时,变量 didScroll 切换为 true,并在下一个间隔(每 250 毫秒)检查它在哪里为 true,然后检查它是否在页面末尾。这种方法效率不高,因为 javascript 会不断评估这个区间函数(我在下一条评论中继续)
  • 所以最好在滚动事件内部评估滚动位置是否接近底部,而不是在区间内。您对 pagecountupdate 的操作取决于您,它与您遇到的问题是分开的。我想它会在某处更新计数器?将新帖子插入页面后,您可能应该运行它
猜你喜欢
  • 1970-01-01
  • 2016-02-25
  • 1970-01-01
  • 2019-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多