0

I've created a fixed sidebar navigation consisting of 3 divs made to look like dots, each representing one of my page sections. Each of those page sections take a 100vh height. Now I am trying to figure out how to determine where on the page is the scroll located and which div am I looking at.

I am using Vue.js which will definitely make things easier to do as soon as I figure out my question.

In order to do that I assume the bare minimum I need would be window.scrollY, OffsetTop and the height of every section in order to determine if the window.scrollY is between the section's OffsetTop ( starting position of the section ) and OffsetTop + height ( ending position of the section ). Am I correct in my thinking so far?

So far I have this:

*, *:after, *:before {
        margin: 0;
        padding: 0;
        -webkit-box-sizing: border-box;
        box-sizing: border-box;
        text-decoration: none;
        list-style-type: none;
        color: rgba(0, 0, 0, 0.8);
    }
    body {
        background-color: #f1f1f1;
        font-family: 'Roboto', 'Helvetica', 'Helvetica Neue', 'Arial', sans-serif;
        background-image: url("./assets/svg/topography.svg");
        background-attachment: fixed;
    }
    section {
        min-height: 100vh;
    }
    .navigation {
        display: flex;
        flex-direction: column;
        position: fixed;
        right: 5%;
        top: 50%;
        transform: translateY(-50%);
        text-align: right;
    }
    .navigation div {
        width: 20px;
        height: 20px;
        border-radius: 50%;
        margin-bottom: 30px;
        transition: all .1s linear;
        border: 5px solid rgba(0, 0, 0, 0.5);
        cursor: pointer;
    }
    .navigation div:hover {
        transform: scale(1.2)
    }
    .one {
    background-color: red;
    }
    .two {
    background-color: blue;
    }
    .three {
    background-color: green;
    }
<nav class='navigation'>
    <div></div>
    <div></div>
    <div></div>
</nav>
<section class='one'></section>
<section class='two'></section>
<section class='three'></section>
Onyx
  • 5,186
  • 8
  • 39
  • 86
  • The javascript approach you had is correct. However, do you want to move the pages so at each given time a page is fully displayed on the screen? or you might have a screen displaying two pages at the same time? – Kalimah Nov 06 '19 at 03:33
  • I don't intend to hijack the scrolling so it will be possible to see 2 of the sections at the same time ( bottom part of top section and top part of lower section ) if the user has scrolled down – Onyx Nov 06 '19 at 03:36

3 Answers3

0

We tried name to navigate in the page between sections is coming from emacs

*, *:after, *:before {
        margin: 0;
        padding: 0;
        -webkit-box-sizing: border-box;
        box-sizing: border-box;
        text-decoration: none;
        list-style-type: none;
        color: rgba(0, 0, 0, 0.8);
    }
    body {
        background-color: #f1f1f1;
        font-family: 'Roboto', 'Helvetica', 'Helvetica Neue', 'Arial', sans-serif;
        background-image: url("./assets/svg/topography.svg");
        background-attachment: fixed;
    }
    section {
        min-height: 100vh;
    }
    .navigation {
        display: flex;
        flex-direction: column;
        position: fixed;
        right: 5%;
        top: 50%;
        transform: translateY(-50%);
        text-align: right;
    }
    .navigation div {
        width: 20px;
        height: 20px;
        border-radius: 50%;
        margin-bottom: 30px;
        transition: all .1s linear;
        border: 5px solid rgba(0, 0, 0, 0.5);
        cursor: pointer;
    }
    .navigation div:hover {
        transform: scale(1.2)
    }
    .one {
    background-color: red;
    }
    .two {
    background-color: blue;
    }
    .three {
    background-color: green;
    }
<nav class='navigation'>
    <div></div>
    <div></div>
    <div></div>
</nav>
<section class='one'></section>
<a name='one'></a>
<section class='two'></section>
<section class='three'></section>
<a href='#one'> go to section one </a>
0

I believe what you are looking for is the pageYOffset property. As shown here and here

var horizontalScroll = window.pageYOffset;
Norae
  • 1
  • 5
0

This code might be a better approach than reading the "traditional" approach of reading element position and height then subtracting that from scroll position.

let totalSections = document.querySelectorAll("section").length;
let sectionHeight = document.querySelector("section").clientHeight;
let totalHeight = totalSections * sectionHeight;

// Change this to 0 if you dont want a threshold. 
let threshold = sectionHeight / 2;

window.addEventListener('scroll', function(e) {
 
  let scrollPosition = window.scrollY + threshold;
 
 // Deduct the scroll position from the total height then divide by section height.
  let position = (totalHeight - scrollPosition) / sectionHeight;
 
 // reverse position
 let final = totalSections - position;
 
 // get section number only
 let sectionNumber = Math.trunc(final);
 
 // get percentage
 let positionPercentage = final - sectionNumber;
 console.log("section", sectionNumber, "percentage", Math.trunc(positionPercentage * 100));
});
*,
*:after,
*:before {
  margin: 0;
  padding: 0;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
  text-decoration: none;
  list-style-type: none;
  color: rgba(0, 0, 0, 0.8);
}

body {
  background-color: #f1f1f1;
  font-family: 'Roboto', 'Helvetica', 'Helvetica Neue', 'Arial', sans-serif;
  background-image: url("./assets/svg/topography.svg");
  background-attachment: fixed;
}

section {
  min-height: 100vh;
}

.navigation {
  display: flex;
  flex-direction: column;
  position: fixed;
  right: 5%;
  top: 50%;
  transform: translateY(-50%);
  text-align: right;
}

.navigation div {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  margin-bottom: 30px;
  transition: all .1s linear;
  border: 5px solid rgba(0, 0, 0, 0.5);
  cursor: pointer;
}

.navigation div:hover {
  transform: scale(1.2)
}

.one {
  background-color: #2ecc71;
}

.two {
  background-color: #9b59b6;
}

.three {
  background-color: #34495e;
}
<nav class='navigation'>
  <div></div>
  <div></div>
  <div></div>
</nav>
<section class='one'></section>
<section class='two'></section>
<section class='three'></section>
Kalimah
  • 11,217
  • 11
  • 43
  • 80