0

I am trying to create a nice load more posts feature when scrolling down the page in a div container and when you reach to the end of the container you see more posts. What i tried so far is working but is buggy when i scroll quite fast as it send more ajax requests then needed and is loading duplicated data.

 <!-- HTML Structure -->
 <header style="position:fixed"></header> 
 <section class="page-banner" style="height: 420px;"></section>
 <section class="projects-general">
    <div class="projects-wrapper">
       <div class="projects-list-wrap"></div>
    </div>
 </section>
 <section class="contact-intro"></section>  
 <footer></footer> 
 <!-- HTML Structure -->
 $(window).scroll(function() {
    var pjCount = $('.pj-col').length;
    var totalPj = $('#pj-numb').val();
    if (pjCount >= totalPj){
        return false;
    }else{
        if($(window).scrollTop() >= $('.projects-list-wrap').offset().top + $('.projects-list-wrap').outerHeight() - window.innerHeight + $('header').outerHeight()) {
            jQuery.ajax({
                url: ajaxURL,
                type: "POST",
                beforeSend: function () {
                    $('.projects-wrapper').append("<div class='pj-loader'></div>");
                },
                complete: function () {
                    $('.pj-loader').remove();
                },
                data:{
                    action: "pj_load_more",
                    pjCount:pjCount
                },
                success:function(data){
                    $('.projects-list-wrap').append(data);
                },
                error: function(err){
                    //console.log(err);
                }
            });
        }
    }
});

Any ideas why it is ok when you try to scroll slowly but when like scrolling fast its creating that buggy effect of duplicating posts. Many thanks

Ana DEV
  • 1,018
  • 2
  • 17
  • 39
  • Take the AJAX call out and write the values in the `if` condition to the console. Then you can see why the state does/does not hit – Rory McCrossan Jan 29 '21 at 18:54
  • @RoryMcCrossan thanks, am trying to check that. – Ana DEV Jan 29 '21 at 19:01
  • You might also consider [debouncing the event handler](https://davidwalsh.name/javascript-debounce-function) to limit how often it fires. It may help to include a [working example](https://stackoverflow.com/help/minimal-reproducible-example) that demonstrates the issue. – showdev Jan 29 '21 at 19:27
  • Can you throw your PHP in to the question as well. – Tony Djukic Jan 29 '21 at 19:30
  • @showdev thanks a lot for the article, i tried but still issue still persist as seems the way am detecting if user reached to position where posts can be loaded has some sort of bug in calculation :( – Ana DEV Jan 29 '21 at 19:37
  • @TonyDjukic php works all good, loads more posts properly, issue is all comign from js thats why posted only js. – Ana DEV Jan 29 '21 at 19:38
  • It's difficult to tell how the scroll position is calculated without seeing your HTML structure (e.g. the `.projects-list-wrap` and `header` elements). – showdev Jan 29 '21 at 19:48
  • @showdev yes for sure, my bad. I updated the question, thanks for pointing that. – Ana DEV Jan 29 '21 at 20:00
  • 1
    I really am tempted to close that with [this answer](https://stackoverflow.com/questions/14035180/jquery-load-more-data-on-scroll) as a duplicate... Please have a look at the condition used there and if it works for you. – Louys Patrice Bessette Jan 29 '21 at 20:51
  • @LouysPatriceBessette no this is not really in my case, i tried it many times :( – Ana DEV Jan 29 '21 at 20:55
  • You tried `$(document).height() - $(window).height()`? That seems more clear and simple to me. Maybe something else is going wrong that isn't reproducible from the code you've shown here. Using your calculation, it doesn't seem that you need to add the header height. Here is a [demonstration of both calculations](https://jsfiddle.net/b02xt9Lf/1/). – showdev Jan 29 '21 at 21:37
  • 1
    I made a [CodePen](https://codepen.io/Bes7weB/pen/RwowJNO) in order to test your condition with the little code you provided. I "feaked" some ajax response... Please edit your question with what is missing... Because that "attempt to reproduce" seems to demonstrate your code is working. – Louys Patrice Bessette Jan 29 '21 at 21:45
  • 1
    Incidentally, `
    ` is invalid HTML.
    – showdev Jan 29 '21 at 21:50
  • I tried $(document).height() - $(window).height() and a lot more tweaks but bug keeps on going. Actually it's because am trying to detect when user scrolls to bottom part of the container so i load more projects and when i do fast scroll seems the end of container is being calculated wrongly and as ajax is in scroll event is being fired multiple times. – Ana DEV Jan 29 '21 at 21:51

1 Answers1

2

Since the ajax call takes time (opposed to my attempt to reproduce) and the scroll event is firing like a machinegun...

The same ajax request could be triggered more than once.

To avoid that, use a flag ajax_request_sent like so:

// A flag to know if a request is sent and the response is not yet received
let ajax_request_sent = false;

$(window).scroll(function() {
  var pjCount = $('.pj-col').length;
  var totalPj = $('#pj-numb').val();
  if (pjCount >= totalPj) {
    return false;
  } else {

    // Use the flag in the condition (so if sent and not yet received == false)
    if (!ajax_request_sent && $(window).scrollTop() >= $('.projects-list-wrap').offset().top + $('.projects-list-wrap').outerHeight() - window.innerHeight + $('header').outerHeight()) {

      // Set the flag to prevent any concurring request
      ajax_request_sent = true
    
      jQuery.ajax({
        url: ajaxURL,
        type: "POST",
        beforeSend: function() {
          $('.projects-wrapper').append("<div class='pj-loader'></div>");
        },
        complete: function() {
          $('.pj-loader').remove();
        },
        data: {
          action: "pj_load_more",
          pjCount: pjCount
        },
        success: function(data) {
          $('.projects-list-wrap').append(data);
          
          // Unset the flag
          ajax_request_sent = false;
        },
        error: function(err) {
          //console.log(err);
        }
      });
      
    }
  }
});
Louys Patrice Bessette
  • 33,375
  • 6
  • 36
  • 64
  • Yaaaay, you saved my day @Louys Patrice Bessette. Issue was exactly the delay time for ajax and really very quick scroll event firing. Your solution worked out perfectly, thanks a million – Ana DEV Jan 29 '21 at 22:08