【问题标题】:How to do an infinite scroll in plain Javascript如何在纯Javascript中进行无限滚动
【发布时间】:2011-06-23 15:43:21
【问题描述】:

我想避免使用 jQuery 或其他库以保持我的代码最少,我需要的功能很少,我只想在用户滚动到底部时附加到列表中。我将如何在纯 Javascript 中做到这一点?

【问题讨论】:

  • 保持你的代码最小化并避免使用像 jQuery 这样的库似乎是相互矛盾的目标,老实说。那么为什么不想使用一个呢?
  • 如果您担心使用像 jQuery 这样的庞大框架来实现这种简单的效果,请考虑使用微框架,您可以在 microjs.com 找到一个很好的列表。实现跨平台兼容的纯js无限滚动将是相当困难的。
  • @Anthony Grist:jQuery 并不总是好的选择:如果你擅长 javascript,那么你可以在特定情况下编写更好的代码;如果您不擅长它,那么使用某些框架编写的代码比没有它的代码更糟糕。总之,jQuery 仅适用于像灯箱这样的封闭解决方案,或者在您没有时间/金钱思考的情况下。我认为不是这种情况。
  • 你是不是在看这样的东西:jsfiddle.net/rathoreahsan/LAR7w
  • @Anthony:在这种情况下,他的意思是尽量减少代码总量,而不是他必须编写的代码量。

标签: javascript firefox scroll infinite-scroll


【解决方案1】:

基本上你只需要钩住事件滚动,检查用户是否向下滚动足够多,如果是的话,添加一些内容:

<html><body>
<div id="test">scroll to understand</div>
<div id="wrapper" style="height: 400px; overflow: auto;">
  <div id="content"> </div>
</div>

<script language="JavaScript">
  // we will add this content, replace for anything you want to add
  var more = '<div style="height: 1000px; background: #EEE;"></div>';

  var wrapper = document.getElementById("wrapper");
  var content = document.getElementById("content");
  var test = document.getElementById("test");
  content.innerHTML = more;

  // cross browser addEvent, today you can safely use just addEventListener
  function addEvent(obj,ev,fn) {
    if(obj.addEventListener) obj.addEventListener(ev,fn,false);
    else if(obj.attachEvent) obj.attachEvent("on"+ev,fn);    
  }

  // this is the scroll event handler
  function scroller() {
    // print relevant scroll info
    test.innerHTML = wrapper.scrollTop+"+"+wrapper.offsetHeight+"+100>"+content.offsetHeight;

    // add more contents if user scrolled down enough
    if(wrapper.scrollTop+wrapper.offsetHeight+100>content.offsetHeight) {
      content.innerHTML+= more;
    }
  }

  // hook the scroll handler to scroll event
  addEvent(wrapper,"scroll",scroller);
</script>
</body></html>

【讨论】:

  • 谢谢,我会试一试,我注意到似乎有效的其他东西(至少在初步测试中)正在测试比较 window.scrollY 和 window.scrollMaxY,我不知道它不过跨浏览器兼容性。
  • window.scrollMaxY 不是跨浏览器。在quirksmode 上有一些兼容性研究。
【解决方案2】:

无限滚动的优秀演示代码。表明您不需要 jQuery 和 Angular 来完成任何独立于浏览器的工作。但是今天的新人与我们老家伙仍然信任和使用的纯 Javascript 脱节了。这里我进一步简化了代码:

// we will add this content, replace for anything you want to add
var wrapper, content, test;
var more = '<div style="height:1000px; background:#EEE;"></div>';

// this is the scroll event handler
function scroller() {
  // print relevant scroll info
  test.innerHTML = wrapper.scrollTop + " + " + wrapper.offsetHeight + " + 100 > " + content.offsetHeight;

  // add more contents if user scrolled down enough
  if (wrapper.scrollTop + wrapper.offsetHeight + 100 > content.offsetHeight) {
    content.innerHTML += more; // NK: Here you can make an Ajax call and fetch content to append to content.innerHTML
  }
}

wrapper = document.getElementById("wrapper");
content = document.getElementById("content");
test = document.getElementById("test");

content.innerHTML = more;

// hook the scroll handler to scroll event
if (wrapper.addEventListener) // NK: Works on all new browsers
  wrapper.addEventListener("scroll", scroller, false);

else if (wrapper.attachEvent) // NK: Works on old IE
  wrapper.attachEvent("onscroll", scroller);
<div id="test">scroll to understand</div>

<div id="wrapper" style="height: 400px; overflow: auto;">
  <div id="content"> </div>
</div>

【讨论】:

    【解决方案3】:

    要实现这种行为,您不需要 jQuery 或 jQuery 插件。您只能使用 CSS 或 JavaScript(如果您想覆盖所有浏览器)。

    但不要使用onScroll:您可以只使用香草JS 和Intersection Observer API 完成所有这些操作。

    您需要做的就是放置元素并在它们出现在屏幕上时进行监听。 Intersection Observer API 非常可定制,可满足您的所有需求。

    总而言之:您只需几行 JavaScript 和 HTML 代码就可以实现这一点,而且它比在浏览器中监听滚动事件的性能要高得多。

    【讨论】:

      【解决方案4】:
      domElem.addEventListener(
              'scroll',
              function(evt) { ... },
              false
          ); 
      

      并适当地处理 evt/scroll 位置。

      【讨论】:

      • @Jan Turoň:问题是关于 Firefox 的。
      【解决方案5】:

      我看到你的问题的好答案,但是对于与任何 HTML 元素或内容(只是一个空的 HTML 页面)无关的滚动,我是这样做的:

      document.querySelector("body").style.height = "1000px";
      
      window.addEventListener("scroll", function() {
          var body = document.querySelector("body");
          var height = body.style.height;
          height = height.slice(0, -2);
          height = Number(height);
          return function() {
              if(height - window.scrollY < 700) {
                  height += height / 2;
              }
              body.style.height = height + "px";
          };
      }());
      <!DOCTYPE html>
      <html>
      <head>
      
      </head>
      <body>
      
      </body>
      </html>

      我希望这可以帮助那里的人:)

      【讨论】:

        【解决方案6】:

        假设 HTML:

        <div class="container"></div>
        
        let container = document.querySelector('.container');
        
        // when user scrolls to last list item in view, wait for 1.5seconds and load next 10 list items, and continue thus.
        window.addEventListener('scroll', function(){
          setTimeout(() => {
            loadMoreList(5);
          }, 1500);
        });
        
        loadMoreList(20); // load first 20 list items.
        
        function loadMoreList(num) {
          let scrollY = window.scrollY;
          let innerHeight = window.innerHeight;
          let offsetHeight = document.body.offsetHeight;
          
          if (scrollY + innerHeight > offsetHeight - 100) {
            let item = 1;
            let ul = document.createElement('ul');
            
            for (var i = 0; i < num; i++) {
              let li = document.createElement('li');
              li.innerText = 'List Item ' + item++;
        
              ul.appendChild(li);
              container.appendChild(ul);
            }
          }
        }
        

        注意:更重要的部分是:scroll 事件监听器和 loadMoreList 函数。您不一定需要参数 num
        for 循环 只是确保在加载时调用该函数并唯一创建和显示 20 个项目。

        【讨论】:

          【解决方案7】:

          具有跨浏览器支持的示例 sn-p:Read inline comments for how it works

          window.onscroll = function(ev) {
              if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
                 //User is currently at the bottom of the page
                  addNewItem();
              }
          };
          
          
          function addNewItem(){
             var itemCount = document.getElementById("movieList").childElementCount;
          const itemLimit = 10; //total number of items to retrieve
          //retrieve the next list of items from wherever
          var nextTopItems = getNextItemSimulator(itemCount); 
          nextTopItems.forEach(function(item) {
          //add the items to your view
            document.getElementById("movieList").innerHTML += "<p>"+item+"</p>"; 
               document.getElementById("footer").style.display = "block";
          });
          setTimeout(function(){
               //remove footer info message
               document.getElementById("footer").style.display = "none";}, 500);
          }
          
          function getNextItemSimulator(currentItem){ 
             //Just some dummy data to simulate an api response
          const dummyItemCount = 50;
          var dummyItems = []; 
          var nextTopDummyItems = [];
          for(i = 1; i <= dummyItemCount; i++){
          //add to main dummy list
              dummyItems.push("Movie " + i);
          }
          var countTen = 10;
          var nextItem = currentItem + 1;
          for(i = nextItem; i <= dummyItems.length; i++){
              //get next 10 records from dummy list
              nextTopDummyItems.push(dummyItems[i - 1]);
              countTen--;
              if(countTen == 0)break;
          }
             return nextTopDummyItems;
          }
          #footer {
              position: fixed;
              bottom: 0;
              width: 100%;
              display:none;
              background: #eee;
          }
          
          #movieList{
          margin-bottom: 20px;
          }
          <h3> Movies 2019 </h3>
          
          <div id="movieList">
          <p>Movie 1</p>
          <p>Movie 2</p>
          <p>Movie 3</p>
          <p>Movie 4</p>
          <p>Movie 5</p>
          <p>Movie 6</p>
          <p>Movie 7</p>
          <p>Movie 8</p>
          <p>Movie 9</p>
          <p>Movie 10</p>
          </div>
          <div id="footer">Loading more movies</div>

          【讨论】:

            猜你喜欢
            • 2022-07-15
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-11-09
            • 2020-04-01
            相关资源
            最近更新 更多