Skip to content Skip to sidebar Skip to footer

Scroll To Section By Section

I have HTML markup: HTML:

Solution 1:

Interesting

I stole this code, changed the layout and tried to add the functions you mentioned (1. scroll-snap + 2. scroll when link is clicked). Unfortunately, I can't have this second function to work.

  1. Adding scroll-snap is not a problem

You need scroll-snap-type: y mandatory; on the container and scroll-snap-align: start; on the sections.

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

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

functionsetScrollPos (pos) {
  context.scrollTop = pos;
}

functiongetClonesHeight () {
  clonesHeight = 0;

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

  return clonesHeight;
}

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

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

functionscrollUpdate () {
  if (!disableScroll) {
    scrollPos = getScrollPos();

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

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

functioninit () {
  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;
}

navul {
  display: flex;
  justify-content: space-around;
  margin: 0;
  padding: 1rem0;
}

navulli{
  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><aclass="nav-link"href="#one">one</a></li><li><aclass="nav-link"href="#two">two</a></li><li><aclass="nav-link"href="#three">three</a></li><li><aclass="nav-link"href="#four">four</a></li><li><aclass="nav-link"href="#five">five</a></li><li><aclass="nav-link"href="#six">six</a></li></ul></nav><mainclass="Loop js-loop"><sectionclass="one"id="one"><h1>One</h1></section><sectionclass="two"id="two"><h1>Two</h1></section><sectionclass="three"id="three"><h1>Three</h1></section><sectionclass="four"id="four"><h1>Four</h1></section><sectionclass="five"id="five"><h1>Five</h1></section><sectionclass="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.
  --><sectionclass="one is-clone"><h1>One</h1></section><sectionclass="two is-clone"><h1>Two</h1></section></main>
  1. Adding the scrolling when you click on the link is a problem

With a normal container you only need to add the scroll-behaviour: smooth; to it. But here if you do that, you will lose the loop illusion because you will see it scroll back to the first instead of seemingly continue. (and it will also start an infinite back and forth scrolling that I couldn't fix yet)

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

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

functionsetScrollPos (pos) {
  context.scrollTop = pos;
}

functiongetClonesHeight () {
  clonesHeight = 0;

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

  return clonesHeight;
}

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

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

functionscrollUpdate () {
  if (!disableScroll) {
    scrollPos = getScrollPos();

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

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

functioninit () {
  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;
}

navul {
  display: flex;
  justify-content: space-around;
  margin: 0;
  padding: 1rem0;
}

navulli{
  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><aclass="nav-link"href="#one">one</a></li><li><aclass="nav-link"href="#two">two</a></li><li><aclass="nav-link"href="#three">three</a></li><li><aclass="nav-link"href="#four">four</a></li><li><aclass="nav-link"href="#five">five</a></li><li><aclass="nav-link"href="#six">six</a></li></ul></nav><mainclass="Loop js-loop"><sectionclass="one"id="one"><h1>One</h1></section><sectionclass="two"id="two"><h1>Two</h1></section><sectionclass="three"id="three"><h1>Three</h1></section><sectionclass="four"id="four"><h1>Four</h1></section><sectionclass="five"id="five"><h1>Five</h1></section><sectionclass="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.
  --><sectionclass="one is-clone"><h1>One</h1></section><sectionclass="two is-clone"><h1>Two</h1></section></main>

I know this code is not 100% functional yet, but I think it can lead us to a better answer.

Solution 2:

You can use ID in this case.

Set the ID for your section and add anchor tag and set href attribute to your section id.

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

Don't forget set scroll-behavior to smooth for smooth scrolling.

Post a Comment for "Scroll To Section By Section"