Search code examples
javascriptinfinite-scroll

Infinite Scrolling with a strange bug


I got on the internet a infinite scrolling script, however it was in jQuery... and since I don't like jquery, I decided to change it to pure JS. When I replaced this $(window).on for this window.addEventListener and this $(window).off("scroll"); for this window.removeEventListener("scroll",... and a bug appeared:

Code running with jQuery - working very well:

<div class="post-item" id="8">8</div>
<div class="post-item" id="7">7</div>
<div class="post-item" id="6">6</div>
<div class="post-item" id="5">5</div>
<div class="post-item" id="4">4</div>
<div class="post-item" id="3">3</div>
<div class="post-item" id="2">2</div>
<div class="post-item" id="1">1</div>

windowOnScroll();
function windowOnScroll() {
  $(window).on("scroll", function(e){
    const {scrollHeight,scrollTop,clientHeight} = document.documentElement
    if (scrollTop + clientHeight > scrollHeight -5){
      if(document.querySelectorAll(".post-item").length < document.getElementById("total_count").value) {
        var lastId = document.querySelectorAll(".post-item");
        var lastchild = lastId[lastId.length-1];
        var id=lastchild.getAttribute("id");
        getMoreData(id);
      }
    }
  });
}
function getMoreData(id) {
  $(window).off("scroll");
  document.querySelector('.ajax-loader').classList.remove("none");
  var formdata=new FormData();
  formdata.append("lastId",id);
  fetch('getMoreData.php',{
    method: 'POST',
    body:formdata
  }).then(function(response){
    response.text().then(function(result){
      setTimeout(function() {
        document.querySelector('.ajax-loader').classList.add("none");
        document.getElementById("post-list").innerHTML+=result;
        windowOnScroll();
      }, 1000);
    })
  }).catch(function(err){ 
    console.error(err);
  });
}

Code running with JS pure - working NOT very well:

<div class="post-item" id="8">8</div>
<div class="post-item" id="7">7</div>
<div class="post-item" id="6">6</div>
<div class="post-item" id="5">5</div>
<div class="post-item" id="4">4</div>
<div class="post-item" id="3">3</div>
<div class="post-item" id="2">2</div>
<div class="post-item" id="4">4</div>
<div class="post-item" id="3">3</div>
<div class="post-item" id="2">2</div>
<div class="post-item" id="4">4</div>
<div class="post-item" id="3">3</div>
<div class="post-item" id="2">2</div>

windowOnScroll();
function windowOnScroll() {
  window.addEventListener("scroll", function(e){
    const {scrollHeight,scrollTop,clientHeight} = document.documentElement
    if (scrollTop + clientHeight > scrollHeight -5){
      if(document.querySelectorAll(".post-item").length < document.getElementById("total_count").value) {
        var lastId = document.querySelectorAll(".post-item");
        var lastchild = lastId[lastId.length-1];
        var id=lastchild.getAttribute("id");
        getMoreData(id);
      }
    }
  });
}
function getMoreData(id) {
  window.removeEventListener("scroll", windowOnScroll());
  document.querySelector('.ajax-loader').classList.remove("none");
  var formdata=new FormData();
  formdata.append("lastId",id);
  fetch('getMoreData.php',{
    method: 'POST',
    body:formdata
  }).then(function(response){
    response.text().then(function(result){
      setTimeout(function() {
        document.querySelector('.ajax-loader').classList.add("none");
        document.getElementById("post-list").innerHTML+=result;
        windowOnScroll();
      }, 1000);
    })
  }).catch(function(err){ 
    console.error(err);
  });

I'm using MYSQL and PHP on the server side.

Any idea to help me???

DEMO


Solution

  • Indeed, the problem was not that.. try this now, I added logic to not make other call until it finishes loading.

    <!DOCTYPE html>
    <html>
      <head>
        <title>How to Create Facebook Like Infinite Scroll Pagination using PHP and jQuery</title>
        <style type="text/css">
          body {
            font-family: Arial;
            background: #e9ebee;
            font-size: 0.9em;
          }
    
          .post-wall {
            background: #fff;
            border: #e0dfdf 1px solid;
            padding: 20px;
            border-radius: 5px;
            margin: 0 auto;
            width: 500px;
          }
    
          .post-item {
            padding: 10px;
            border: #f3f3f3 1px solid;
            border-radius: 5px;
            margin-bottom: 30px;
          }
    
          .post-title {
            color: #4faae6;
          }
    
          .ajax-loader {
            display: block;
            text-align: center;
          }
          .none {
            display: none;
          }
          .ajax-loader img {
            width: 50px;
            vertical-align: middle;
          }
        </style>
      </head>
      <body>
        <div class="post-wall">
          <div id="post-list">
            <input type="hidden" name="total_count" id="total_count" value="22" />
    
            <div class="post-item" id="22">
              <p class="post-title">Ajax live search using jQuery Ajax and PHP</p>
              <p>Ajax live search is a search form where you get search results instantly while you type. Therefore i</p>
            </div>
            <div class="post-item" id="21">
              <p class="post-title">Live image preview before upload to the server using jQuery</p>
              <p>Sometimes it is required to verify the selected image before upload it to the server. So, in this tu</p>
            </div>
            <div class="post-item" id="20">
              <p class="post-title">Count words and characters using jQuery</p>
              <p>A simple, word and character counter for HTML textarea and other input fields. The following simple</p>
            </div>
            <div class="post-item" id="19">
              <p class="post-title">Write data into CSV file using PHP</p>
              <p>Sometimes we need to generate CSV file containing data from database table. So, in this tutorial, we</p>
            </div>
            <div class="post-item" id="18">
              <p class="post-title">Read CSV file using PHP</p>
              <p>Read CSV file using PHP is very easy and simple. PHP has a built function fgetcsv(), through which w</p>
            </div>
          </div>
          <div class="ajax-loader none text-center"><img src="LoaderIcon.gif" /> Loading more posts...</div>
        </div>
    
        <script type="text/javascript">
          var isLoading = false;
    
          window.addEventListener("scroll", function () {
            const { scrollHeight, scrollTop, clientHeight } = document.documentElement;
            if (
              scrollTop + clientHeight > scrollHeight - 5 &&
              document.querySelectorAll(".post-item").length < document.getElementById("total_count").value
            ) {
              var lastId = document.querySelectorAll(".post-item");
              var lastchild = lastId[lastId.length - 1];
              var id = lastchild.getAttribute("id");
              getMoreData(id);
            }
          });
    
          function getMoreData(id) {
            if (isLoading) return;
    
            isLoading = true;
    
            document.querySelector(".ajax-loader").classList.remove("none");
            var formdata = new FormData();
            formdata.append("lastId", id);
            fetch("getMoreData.php", {
              method: "POST",
              body: formdata,
            })
              .then(function (response) {
                response.text().then(function (result) {
                  setTimeout(function () {
                    document.querySelector(".ajax-loader").classList.add("none");
                    document.getElementById("post-list").innerHTML += result;
                    isLoading = false;
                  }, 1000);
                });
              })
              .catch(function (err) {
                console.error(err);
                isLoading = false;
              });
          }
        </script>
      </body>
    </html>