滚动到逐节

时间:2013-10-02 10:34:48

标签: javascript jquery html css

我有HTML标记:

HTML:

<body>
    <header></header>

    <nav>
        <ul>
            <li><a href="#one">one</a></li>
            <li><a href="#two">two</a></li>
        </ul>
    </nav>

    <section id="one"></section>
    <section id="two"></section>

    <footer></footer>
</body>

其中部分为全屏(宽度:100%;高度:100%;)和菜单具有绝对位置。

问题:

  1. 如何使用鼠标滚动(或键)滚动并捕捉到每个部分?
  2. 滚动到最后部分,然后再次向下滚动到#one 并重复此操作。
  3. 当我点击链接时,它会滚动到部分。
  4. 感谢您的建议,想法,代码。

3 个答案:

答案 0 :(得分:16)

如果您想要与旧版浏览器(如IE8,9,Opera 12等)的更多兼容性以及更多功能,我创建了一个JavaScript库,您可以使用 fullPage.js

它提供的一些功能:

  • 与旧版浏览器兼容,例如IE 8,不支持CSS 3。
  • 使用菜单和导航项目符号链接各个部分
  • 部分和幻灯片的网址锚
  • 响应高度和宽度选项
  • 回调和数十种选项和方法
  • 支持水平滑块
  • 触摸支持移动设备,平板电脑和触摸屏桌面
  • 使用键盘快捷键
  • 滑动页面

此外:

答案 1 :(得分:2)

在这种情况下,您可以使用ID。

设置您的部分的ID,并添加锚标记,并将href属性设置为您的部分ID。

<a href="#YourSectionID">Go Up</a> <!-- don't forget # before write your ID. -->

别忘了将滚动行为设置为平滑滚动。

答案 2 :(得分:1)

有趣

我偷了this code,更改了布局并尝试添加您提到的功能(1.滚动捕捉+ 2.单击链接时滚动)。 不幸的是,我无法使用第二个功能。

  1. 添加滚动快照不是问题

您需要在容器上scroll-snap-type: y mandatory;,在各部分上scroll-snap-align: start;

var doc = window.document,
  context = doc.querySelector('.js-loop'),
  clones = context.querySelectorAll('.is-clone'),
  disableScroll = false,
  scrollHeight = 0,
  scrollPos = 0,
  clonesHeight = 0,
  i = 0;

function getScrollPos () {
  return (context.pageYOffset || context.scrollTop) - (context.clientTop || 0);
}

function setScrollPos (pos) {
  context.scrollTop = pos;
}

function getClonesHeight () {
  clonesHeight = 0;

  for (i = 0; i < clones.length; i += 1) {
    clonesHeight = clonesHeight + clones[i].offsetHeight;
  }

  return clonesHeight;
}

function reCalc () {
  scrollPos = getScrollPos();
  scrollHeight = context.scrollHeight;
  clonesHeight = getClonesHeight();

  if (scrollPos <= 0) {
    setScrollPos(1); // Scroll 1 pixel to allow upwards scrolling
  }
}

function scrollUpdate () {
  if (!disableScroll) {
    scrollPos = getScrollPos();

    if (clonesHeight + scrollPos >= scrollHeight) {
      // Scroll to the top when you’ve reached the bottom
      setScrollPos(1); // Scroll down 1 pixel to allow upwards scrolling
      disableScroll = true;
    } else if (scrollPos <= 0) {
      // Scroll to the bottom when you reach the top
      setScrollPos(scrollHeight - clonesHeight);
      disableScroll = true;
    }
  }

  if (disableScroll) {
    // Disable scroll-jumping for a short time to avoid flickering
    window.setTimeout(function () {
      disableScroll = false;
    }, 40);
  }
}

function init () {
  reCalc();
  
  context.addEventListener('scroll', function () {
    window.requestAnimationFrame(scrollUpdate);
  }, false);

  window.addEventListener('resize', function () {
    window.requestAnimationFrame(reCalc);
  }, false);
}

if (document.readyState !== 'loading') {
  init()
} else {
  doc.addEventListener('DOMContentLoaded', init, false)
}
html,
body {
  height: 100%;
  overflow: hidden;
}

.Loop {
  position: relative;
  height: 100%;
  overflow: scroll;
  -webkit-overflow-scrolling: touch;
  scroll-snap-type: y mandatory;
}

section {
  position: relative;
  text-align: center;
  height: 100%;
  scroll-snap-align: start;
}

::scrollbar {
  display: none;
}


body {
  font-family: "Avenir Next", Helvetica, sans-serif;
  font-weight: normal;
  font-size: 100%;
  position: relative;
}

nav {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  z-index: 10;
}

nav ul {
  display: flex;
  justify-content: space-around;
  margin: 0;
  padding: 1rem 0;
}

nav ul li{
  display: flex;
  justify-content: space-around;
}

.nav-link{
  text-decoration: none;
  color: grey
}

.one {
  background: black;
}
.two {
  background: darkblue;
}
.three {
  background: lightgreen;
}
.four {
  background: lightcoral;
}
.five {
  background: lightskyblue;
}
.six {
  background: orange;
}

h1 {
  margin: 0;
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 100%;
  font-size: 80px;
  letter-spacing: 5px;
  color: #fff;
  text-transform: uppercase;
}
<nav>
  <ul>
    <li><a class="nav-link" href="#one">one</a></li>
    <li><a class="nav-link" href="#two">two</a></li>
    <li><a class="nav-link" href="#three">three</a></li>
    <li><a class="nav-link" href="#four">four</a></li>
    <li><a class="nav-link" href="#five">five</a></li>
    <li><a class="nav-link" href="#six">six</a></li>
  </ul>
</nav>
<main class="Loop js-loop">
  <section class="one" id="one">
    <h1>One</h1>
  </section>
  <section class="two" id="two">
    <h1>Two</h1>
  </section>
  <section class="three" id="three">
    <h1>Three</h1>
  </section>
  <section class="four" id="four">
    <h1>Four</h1>
  </section>
  <section class="five" id="five">
    <h1>Five</h1>
  </section>
  <section class="six" id="six">
    <h1>Six</h1>
  </section>

  <!--
  These 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="one is-clone">
    <h1>One</h1>
  </section>
  <section class="two is-clone">
    <h1>Two</h1>
  </section>

</main>

  1. 单击链接时添加滚动条是一个问题

使用普通容器,您只需向其添加scroll-behaviour: smooth;。但是,如果这样做,您将失去循环幻觉,因为您会看到它向后滚动后退到第一个,而不是看似继续。 (它还将开始无限的来回滚动,而我尚无法解决)

var doc = window.document,
  context = doc.querySelector('.js-loop'),
  clones = context.querySelectorAll('.is-clone'),
  disableScroll = false,
  scrollHeight = 0,
  scrollPos = 0,
  clonesHeight = 0,
  i = 0;

function getScrollPos () {
  return (context.pageYOffset || context.scrollTop) - (context.clientTop || 0);
}

function setScrollPos (pos) {
  context.scrollTop = pos;
}

function getClonesHeight () {
  clonesHeight = 0;

  for (i = 0; i < clones.length; i += 1) {
    clonesHeight = clonesHeight + clones[i].offsetHeight;
  }

  return clonesHeight;
}

function reCalc () {
  scrollPos = getScrollPos();
  scrollHeight = context.scrollHeight;
  clonesHeight = getClonesHeight();

  if (scrollPos <= 0) {
    setScrollPos(1); // Scroll 1 pixel to allow upwards scrolling
  }
}

function scrollUpdate () {
  if (!disableScroll) {
    scrollPos = getScrollPos();

    if (clonesHeight + scrollPos >= scrollHeight) {
      // Scroll to the top when you’ve reached the bottom
      setScrollPos(1); // Scroll down 1 pixel to allow upwards scrolling
      disableScroll = true;
    } else if (scrollPos <= 0) {
      // Scroll to the bottom when you reach the top
      setScrollPos(scrollHeight - clonesHeight);
      disableScroll = true;
    }
  }

  if (disableScroll) {
    // Disable scroll-jumping for a short time to avoid flickering
    window.setTimeout(function () {
      disableScroll = false;
    }, 40);
  }
}

function init () {
  reCalc();
  
  context.addEventListener('scroll', function () {
    window.requestAnimationFrame(scrollUpdate);
  }, false);

  window.addEventListener('resize', function () {
    window.requestAnimationFrame(reCalc);
  }, false);
}

if (document.readyState !== 'loading') {
  init()
} else {
  doc.addEventListener('DOMContentLoaded', init, false)
}
html,
body {
  height: 100%;
  overflow: hidden;
}

.Loop {
  position: relative;
  height: 100%;
  overflow: scroll;
  -webkit-overflow-scrolling: touch;
  scroll-snap-type: y mandatory;
  scroll-behavior: smooth;
}

section {
  position: relative;
  text-align: center;
  height: 100%;
  scroll-snap-align: start;
}

::scrollbar {
  display: none;
}


body {
  font-family: "Avenir Next", Helvetica, sans-serif;
  font-weight: normal;
  font-size: 100%;
  position: relative;
}

nav {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  z-index: 10;
}

nav ul {
  display: flex;
  justify-content: space-around;
  margin: 0;
  padding: 1rem 0;
}

nav ul li{
  display: flex;
  justify-content: space-around;
}

.nav-link{
  text-decoration: none;
  color: grey
}

.one {
  background: black;
}
.two {
  background: darkblue;
}
.three {
  background: lightgreen;
}
.four {
  background: lightcoral;
}
.five {
  background: lightskyblue;
}
.six {
  background: orange;
}

h1 {
  margin: 0;
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 100%;
  font-size: 80px;
  letter-spacing: 5px;
  color: #fff;
  text-transform: uppercase;
}
<nav>
  <ul>
    <li><a class="nav-link" href="#one">one</a></li>
    <li><a class="nav-link" href="#two">two</a></li>
    <li><a class="nav-link" href="#three">three</a></li>
    <li><a class="nav-link" href="#four">four</a></li>
    <li><a class="nav-link" href="#five">five</a></li>
    <li><a class="nav-link" href="#six">six</a></li>
  </ul>
</nav>
<main class="Loop js-loop">
  <section class="one" id="one">
    <h1>One</h1>
  </section>
  <section class="two" id="two">
    <h1>Two</h1>
  </section>
  <section class="three" id="three">
    <h1>Three</h1>
  </section>
  <section class="four" id="four">
    <h1>Four</h1>
  </section>
  <section class="five" id="five">
    <h1>Five</h1>
  </section>
  <section class="six" id="six">
    <h1>Six</h1>
  </section>

  <!--
  This block is the same as the first block to get that looping illusion going.
  You need to add clones to fill out a full viewport height.
  -->
  <section class="one is-clone">
    <h1>One</h1>
  </section>
  <section class="two is-clone">
    <h1>Two</h1>
  </section>

</main>

我知道这段代码还不能100%起作用,但是我认为它可以使我们找到更好的答案。