双向无限滚动 - 向上和向下

时间:2012-05-13 09:28:47

标签: javascript jquery html5 scroll

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

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

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

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

还有其他潜在客户?

6 个答案:

答案 0 :(得分:4)

  

还有其他潜在客户?

看到这些?

5 jQuery infinite Scrolling Demos

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

答案 1 :(得分:3)

好的......我把它解决了。

我改编了this script,当你到达顶部时,它会立即将滚动位置重新定位到页面顶部。

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

然后我确保页面底部和顶部的内容相同。我认为当这次重新安置发生时会有一些闪光或什么东西,但它很顺利!

答案 2 :(得分:2)

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

答案 3 :(得分:2)

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

我给你留下了一些片段。

  

首先,一些背景知识。我们为什么要假设滚动条开始?

     

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

进一步向下......

  

然后,它会监听wheel事件,但从不对它们调用preventDefault或者为了响应它们而滚动。相反,它通过设置超时来响应轮子事件滚动内容的像素数量,并使用它来调整运行时的delta-to-pixel速率。

答案 4 :(得分:0)

依靠马哈茂德的答案,我在几分钟内就把它搞砸了。

当使用键或鼠标滚轮滚动时,它有点(至少在Firefox上),但拖动滚动条时会出现所有问题。根据{{​​1}}高度与视口高度的关系,各种烟花也会发生。

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

                   

div

答案 5 :(得分:0)

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

/*
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>