duanli6618 2014-07-19 03:54
浏览 54
已采纳

加载“无限”滚动的AJAX数据不正确

I'm currently working on a script that loads content when either you trigger it (by clicking a link), or you scroll to the bottom of the page. I'm doing this for fun, but it is slowly turning into a nightmare... The triggered part works correctly, while the "scroll to the bottom" part sometimes works and sometimes doesn't. It will sometimes load a post twice, and sometimes repeat the sets of posts (I'm loading 5 at a time) and not display the next set, my guess is that it is because it loads content so fast, that:

  1. The queries get all mixed up (AJAX calls/mysql queries/Responses...?) or...
  2. There's some kind of problem with the DOM (I guess this is the correct way of calling this...) or...
  3. It is the cause of another glitch that I can't currently think of because of my basic knowledge...

The problem arises when you keep the scroll bar down, and so it loads the content very fast, it is especially a problem with Firefox, since if you are already at the bottom and refresh the page, it will load indefinitely until there are no more posts, and again, it does it really fast.

I've tried different approaches, all day... and I can't find a solution. First, I tried setting a flag, so that when each AJAX call finishes, it increases a certain variable by the number of posts loaded, and will only execute the call again if the number has been increased, and it must do so orderly (which in my head meant succesful AJAX call). This didn't work.

Then I tried setting a timeout, for the AJAX call, and then for the function that contains that call, and then for the function that executes the function in the first place (scrolling to the bottom), this kind of worked, but with the drawback of it not doing anything for that timeout (and thus, not even displaying the "loading" html) and with the situation happening fewer times, but still happening. I also tried setting the timeout in the $.ajax() function, which I think is a different kind of timeout, because it did not do what I desired...

Finally, I tried making async false, which I read is a bad thing, because it hangs the page until it's done, and because it is also deprecated; needless to say, it didn't work either (I didn't notice any visible change in behaviour).

I'm really lost here; I'm not even sure why this "glitch" happens...

Here's my code...

    $.ajax({    //Removed some code in order to make it brief                             
  url: 'load.php',        
  type: 'post',     
  dataType: 'json',       
  data: {offset: countContent, limit: displayNumber},
  success: function(data)         
  {
           if(data)
           {
            for(var i=0;i<display_n;i++)
                     {
            var title = data[i][1];
            var author = data[i][2];
            var img = data[i][3];
            var date = data[i][4];
            var htmlStr = 
            '<div class="post" id="'+i+'"></div>';
           $(element).append(htmlStr);
           $(element).children('#'+i+':last').hide().fadeIn(200+(i*250));
                      }
            }
           else if(data == null){

             //Do something when there are no more posts
          }

  },
  error: function() { 
         // Error     
                     }

});

And the php that processes the ajax call

<?php
$offset = (int) $_POST['offset'];
$limit = (int) $_POST['limit'];
$db = 'mysql:host=localhost;dbname=posts;charset=utf8';
$u = 'username';
$p = 'password';
$con = new PDO($db,$u,$p);
$q = $con->prepare("SELECT id, title, author, img, date FROM articles 
ORDER BY id DESC LIMIT :limit OFFSET :offset");
$q->bindParam(':offset',$offset,PDO::PARAM_INT);
$q->bindParam(':limit',$limit,PDO::PARAM_INT);
$q->execute();
$articles = $q->fetchAll(PDO::FETCH_NUM);
$con = null;
$array_count = count($articles);
if ($articles){
 for ($i=0;$i<$array_count;$i++)
   {
$articles[$i][4] = date("d F Y",strtotime($articles[$i]['4'])); 
  }
   echo json_encode($articles);
  }
 else
 {
  $articles = null; //sends null if the data is empty
 echo json_encode($articles);
 }
?>

Is there any way to "delay" the ajax call before the other one gets executed, so that the articles load correctly? Or wait till everything in the ajax loaded as according to plan before going to the next one? What can I do in this case?

I'm sorry if this post is kind of huge, I guess I wanted to make a point, ha. Help is very much appreciated, thanks.

EDIT: Here's what I posted below, and the solution:

I set a global variable running to false, and wrapped the whole AJAX call inside an if !running condition, immediatly making the variable true after entering the loop, and making it false again on either the "complete: " parameter of the $.ajax function or via $.ajaxComplete(). I'm guessing one can also use .on() and .off() statements to bind and unbind the event trigger, but I found the previous method so much more simple.

This allows the AJAX call to finish before the other one starts, and the content is displayed correctly.

  • 写回答

1条回答 默认 最新

  • doutou6803 2014-07-19 04:02
    关注

    I suggest you turn off the event trigger right after it's been triggered, and turn it back on after you populated the DOMs.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 2024-五一综合模拟赛
  • ¥15 下图接收小电路,谁知道原理
  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度
  • ¥30 关于#r语言#的问题:如何对R语言中mfgarch包中构建的garch-midas模型进行样本内长期波动率预测和样本外长期波动率预测
  • ¥15 ETLCloud 处理json多层级问题
  • ¥15 matlab中使用gurobi时报错
  • ¥15 这个主板怎么能扩出一两个sata口
  • ¥15 不是,这到底错哪儿了😭