Search code examples
javascriptgoogle-chromescroll

Infinite scrolling catches on vigorous scrolling/swiping in google chrome


I have an infinite scroll box. There is a list of items and as the list scrolls up, items are appended from the bottom, and vice versa for scrolling down. When the user scrolls down or up normally, it works as expected. When they scroll with a laptop trackpad or on a screen with enough force, then the scroll bar reaches the top and the user needs to scroll down again for it work. Is there a way to get around this?

Here's a codepen link to what I'm trying to do. Seems like it won't scroll down on load in codepen (this is not the problem so please ignore), please scroll down a bit for it to work. I can produce the described behavior when I use a laptop trackpad or touch screen, I swipe down so the list moves upwards. Hope this wasn't confusing - basically I want the scroll bar to never reach the top no matter how hard a user scrolls/swipes.

let container = document.querySelector('.calendar-container')
let calendar = document.querySelector('.calendar')

container.addEventListener('scroll', function (event) {

  const factor = container.scrollTop / (container.scrollHeight - container.offsetHeight);
  if(factor < 0.4) {
      let move = calendar.querySelector(':last-child')
      move.remove();
      calendar.prepend(move);
  } else if(factor > 0.6) {
      let move = calendar.querySelector(':first-child')
      move.remove();
      calendar.append(move);
  }

});

calendar.scroll(0,100);

As per the comments, right now this only an issue in chrome


Solution

  • Well, I found a hacky solution but will be open to see others if anyone else has a better fix, just add this to the end of the scroll event

      if (document.querySelector('.calendar-container').scrollTop < 10) {
          document.querySelector('.calendar-container').scroll(0,150)
       }
    

    });

    let container = document.querySelector('.calendar-container')
    let calendar = document.querySelector('.calendar')
    
    container.addEventListener('scroll', function(event) {
    
      const factor = container.scrollTop / (container.scrollHeight - container.offsetHeight);
      if (factor < 0.4) {
        let move = calendar.querySelector(':last-child')
        move.remove();
        calendar.prepend(move);
      } else if (factor > 0.6) {
        let move = calendar.querySelector(':first-child')
        move.remove();
        calendar.append(move);
      }
      if (document.querySelector('.calendar-container').scrollTop < 10) {
        document.querySelector('.calendar-container').scroll(0, 150)
      }
    });
    
    calendar.scroll(0, 100);
    * {
      box-sizing: border-box;
    }
    
    .container {
      display: flex;
      flex-direction: column;
      align-items: center;
    }
    
    .calendar-container {
      height: 300px;
      width: 500px;
      text-align: center;
      overflow: hidden;
      overflow-y: scroll;
    }
    
    ::-webkit-scrollbar {
      /* width: 0px;
      background: transparent;  */
    }
    
    .calendar {
      padding: 0;
    }
    
    .calendar-container li {
      display: inline-block;
      width: 80%;
      order: 5;
      height: 50px;
      margin-top: 1px;
      border-radius: 10px;
      background: #eee;
      font-size: 20px;
    }
    <div class="container">
      <div class="calendar-container">
    
        <ul class="calendar">
    
          <li class="calendar-hour" data-date="" data-hour="0"></li>
          <li class="calendar-hour" data-date="" data-hour="1"></li>
          <li class="calendar-hour" data-date="" data-hour="2"></li>
          <li class="calendar-hour" data-date="" data-hour="3"></li>
          <li class="calendar-hour" data-date="" data-hour="4"></li>
          <li class="calendar-hour" data-date="" data-hour="5"></li>
          <li class="calendar-hour" data-date="" data-hour="6"></li>
          <li class="calendar-hour" data-date="" data-hour="7"></li>
          <li class="calendar-hour" data-date="" data-hour="8"></li>
          <li class="calendar-hour" data-date="" data-hour="9"></li>
          <li class="calendar-hour" data-date="" data-hour="10"></li>
          <li class="calendar-hour" data-date="" data-hour="11"></li>
          <li class="calendar-hour" data-date="" data-hour="12"></li>
          <li class="calendar-hour" data-date="" data-hour="13"></li>
          <li class="calendar-hour" data-date="" data-hour="14"></li>
          <li class="calendar-hour" data-date="" data-hour="15"></li>
          <li class="calendar-hour" data-date="" data-hour="16"></li>
          <li class="calendar-hour" data-date="" data-hour="17"></li>
          <li class="calendar-hour" data-date="" data-hour="18"></li>
          <li class="calendar-hour" data-date="" data-hour="19"></li>
          <li class="calendar-hour" data-date="" data-hour="20"></li>
          <li class="calendar-hour" data-date="" data-hour="21"></li>
          <li class="calendar-hour" data-date="" data-hour="22"></li>
          <li class="calendar-hour" data-date="" data-hour="23"></li>
        </ul>
      </div>
    </div>