【问题标题】:Infinite scrolling in both directions - Up and down双向无限滚动 - 向上和向下
【发布时间】:2012-05-13 09:28:46
【问题描述】:

我正在尝试创建一个向上和向下无限滚动循环的页面。

目前我正在使用 jquery 将内容从页面顶部重新定位到底部。当您向下滚动时,这会创建一个很好的无缝循环,但我希望它在用户向上滚动时也能工作。

问题似乎是即使内容位于页面上的负垂直空间中,滚动也不会延伸到该空间。据我所知,没有办法覆盖它,所以我正在寻找某种解决方法。

我想使用 javascript 来禁用滚动并使用滚动事件来重新定位元素,但是页面上已经有很多绝对定位的元素和动画,所以我担心采用这条路线的性能。

还有其他线索吗?

【问题讨论】:

  • 你好。我想知道您是如何实现已有的滚动循环的。谢谢

标签: javascript jquery html scroll


【解决方案1】:

好的...我解决了。

我调整了this script,它会在您到达底部时立即将滚动位置重新定位到页面顶部,并在您到达顶部时将滚动位置重新定位到底部。

$(window).scroll(function() {
    if ( $(window).scrollTop() >= 18830 ) {
        $(window).scrollTop(201);
    }
    else if ( $(window).scrollTop() == 0 ) {
        $(window).scrollTop(18629);
    }    
});

然后我确保页面底部和顶部的内容是相同的。原以为这次搬迁的时候会有闪现之类的,但是很顺利!

【讨论】:

  • “我写了这个脚本”你知道这和我发布的小提琴中的代码是一样的吗?
  • 抱歉。我刚刚注意到这一点。我并没有故意试图欺骗人们认为是我从头开始编写脚本。这是一个诚实的错误。
【解决方案2】:

我最喜欢的解决方案是this one (code),因为它在底部到达底部之前添加元素,确保滚动保持连续(即使使用@987654323 @scrolling 开)。但是,它在滚动可能很快发生的手机上效果不佳。我推荐 Marijn Haverbeke 的 wonderful article 在 CodeMirror 中处理类似问题的假滚动条。

我留给你一些 sn-ps。

首先,一些背景。为什么我们要先伪造一个滚动条?

为了在加载大量文档时保持响应,CodeMirror 不会渲染整个文档,而只会渲染当前滚动到视图中的部分。这意味着它创建的 DOM 节点的数量受到视口大小的限制,并且由文本更改触发的浏览器重新布局相对便宜。

再往下……

然后,它会监听滚轮事件,但从不对它们调用 preventDefault 或滚动响应它们。相反,它通过设置超时来响应,以观察滚轮事件滚动内容的像素数量,并在运行时使用它来调整其增量到像素的速率。

【讨论】:

    【解决方案3】:

    克隆您的 HTML 正文两次(或三次)(使用 javascript 或其他方式)。从中间副本而不是顶部开始页面,然后您可以随意处理滚动。

    【讨论】:

    • hmm... 但是滚动到 top:0px 位置似乎是不可能的,即使您确实有元素放置在该点之外。
    • 您将不再使用该语法。暂时搁置您的方法,想象一个简单的、无 JS 的页面,其中包含一些 HTML 元素。克隆内容。滚动到第一个副本的末尾(第二个副本的开头)。不能上下滚动吗?
    • 一旦用户开始滚动,您就开始从下到上移动数据。但是由于您不是从顶部开始,因此用户不会达到滚动限制。
    【解决方案4】:

    还有其他线索吗?

    看到这些了吗?

    5 jQuery infinite Scrolling Demos

    jsfiddle that I cannot find origin of.(我没写也不知道是谁写的)

    【讨论】:

    • 这些都没有上下无限滚动。
    【解决方案5】:

    根据 Mahmoud 的回答,我在几分钟内就破解了这个问题。

    在使用键或鼠标滚轮滚动时,它有点工作(至少在 Firefox 上),但在拖动滚动条时会出现故障。根据div 高度与视口高度的关系,各种烟花也可能发生。

    不过,我希望这可以帮助您找到正确的方向。

    function onScroll(){
        var SAFETY_MARGIN = 50,
            scrollPos = $(this).scrollTop(),
            docHeight = $(document.body).height(),
            winHeight = $(window).height(),
            firstDiv = $('body>div:first-child')[0],
            lastDiv = $('body>div:last-child')[0],
            lowerLimit = SAFETY_MARGIN,
            higherLimit = docHeight - SAFETY_MARGIN;
    
        // Scrolling too high
        if( scrollPos <= lowerLimit ){
    
            // Move content to top;
            $(lastDiv).prependTo(document.body);
    
            // Adjust scroll position to compensate
            // for the new content at the top
            $(window).scrollTop(scrollPos + $(lastDiv).height());
    
        }
    
        // Scrolling too low
        else if( scrollPos + winHeight >= higherLimit ){
    
            // Move content to bottom
            $(firstDiv).appendTo(document.body);
    
            // Adjust scroll position to compensate
            // for the missing content at the top
            $(window).scrollTop(scrollPos - $(firstDiv).height());
        } 
    }
    
    
    $(window).scroll(onScroll);
    
    $(window).load(function(){
        var $body = $(document.body);
        $(window).scrollTop($body.height() / 2);
    });
    
    </script>
    </head>
    <body>
    
    <div style="height: 600px; background-color: red">&nbsp;</div>
    <div style="height: 600px; background-color: green">&nbsp;</div>
    <div style="height: 600px; background-color: blue">&nbsp;</div>
    
    </body>
    </html>
    

    【讨论】:

      【解决方案6】:

      正如许多人所建议的那样,如果您的页面在顶部和底部看起来并不完全相同,您需要克隆您的内容以使其看起来像它一样。我使用这种技术制作了一个非常流畅的示例:

      /*
      Ininite looping scroll.
      Tested and works well in latest Chrome, Safari and Firefox.
      */
      
      (function (window) {
        'use strict';
      
        var doc = document,
          body = doc.body,
          html = doc.documentElement,
          startElement = doc.getElementsByClassName('is-start')[0],
          clones = doc.getElementsByClassName('is-clone'),
          disableScroll = false,
          docHeight,
          scrollPos,
          clonesHeight,
          i;
      
        function getScrollPos() {
          return (window.pageYOffset || html.scrollTop)  - (html.clientTop || 0);
        }
      
        function getDocHeight() {
          return Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight);
        }
      
        function getClonesHeight() {
          i = 0;
          clonesHeight = 0;
      
          for (i; i < clones.length; i += 1) {
            clonesHeight = clonesHeight + clones[i].offsetHeight;
          }
      
          return clonesHeight;
        }
      
        docHeight = getDocHeight();
        clonesHeight = getClonesHeight();
      
        window.addEventListener('resize', function () {
          scrollPos = getScrollPos();
          docHeight = getDocHeight();
          clonesHeight = getClonesHeight();
      
          if (scrollPos <= 0) {
            window.scroll(0, 1); // Scroll 1 pixel to allow upwards scrolling.
          }
        }, false);
      
        window.addEventListener('scroll', function () {
          if (disableScroll === false) {
            scrollPos = getScrollPos();
      
            if (clonesHeight + scrollPos >= docHeight) {
              // Scroll to the top when you’ve reached the bottom
              window.scroll(0, 1); // Scroll 1 pixel to allow upwards scrolling.
              disableScroll = true;
            } else if (scrollPos <= 0) {
              // Scroll to the top of the clones when you reach the top.
              window.scroll(0, docHeight - clonesHeight);
              disableScroll = true;
            }
      
            if (disableScroll) {
              // Disable scroll-repositioning for a while to avoid flickering.
              window.setTimeout(function () {
                disableScroll = false;
              }, 100);
            }
          }
        }, false);
      
        // Needs a small delay in some browsers.
        window.setTimeout(function () {
          if (startElement) {
            // Start at the middle of the starting block.
            window.scroll(0, Math.round(startElement.getBoundingClientRect().top + document.body.scrollTop - (window.innerHeight - startElement.offsetHeight) / 2));
          } else {
            // Scroll 1 pixel to allow upwards scrolling.
            window.scroll(0, 1);
          }
        });
      
      }(this));
      section {
        position: relative;
        text-align: center;
        height: 80vh;
      }
      
      .red {
        background: #FF4136;
      }
      .green {
        background: #2ECC40;
      }
      .blue {
        background: #0074D9;
      }
      .orange {
        background: rebeccapurple;
      }
      
      h1 {
        margin: 0;
        position: absolute;
        top: 50%;
        transform: translateY(-50%);
        width: 100%;
      
        font-size: 5vw;
        color: #fff;
        text-transform: uppercase;
      }
      
      body {
        font-family: "Avenir Next", Montserrat, Helvetica, sans-serif;
        font-weight: normal;
        font-size: 100%;
      }
      
      ::scrollbar {
        display: none;
      }
      <section class="green">
        <h1>One</h1>
      </section>
      <section class="red">
        <h1>For</h1>
      </section>
      <section class="blue">
        <h1>All</h1>
      </section>
      <section class="orange">
        <h1>And</h1>
      </section>
      <section class="blue">
        <h1>All</h1>
      </section>
      <section class="red">
        <h1>For</h1>
      </section>
      
      <!--
      These following blocks are the same as the first blocks to get that looping illusion going. You need to add clones to fill out a full viewport height.
      -->
      <section class="green is-clone is-start">
        <h1>One</h1>
      </section>
      <section class="red is-clone">
        <h1>For</h1>
      </section>

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-01-19
        • 1970-01-01
        • 1970-01-01
        • 2015-07-17
        • 2015-09-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多