How to know if the scroll position is on top of a Section?

Asked

Viewed 1,687 times

4

I don’t know if it was clear, but I’ll illustrate, I have several sections on my site, and when I give scroll I wanted to perform some effects with Javascript, how do I know to know when exactly the user will be viewing the div, as in Boostrap’s Scroll Spy? I tried pageYoffset, but the measures vary according to the resolution.

2 answers

4

Just check if the scrollTop() is greater than or equal to position(). top of the section you want to check, the scrollTop() returns the current vertical position of the scroll bar, the position().top the position of the element relative to its father.

*Note that in the example I check if the scroll position is between the beginning of the interest section and the beginning of next section, that is, ensuring that it is on the correct section.

*Note also that in this context the offset(). top would also work, because the parent element of section's is the very Document.

Follow a snippet of example:

$(document).on('scroll', function() {
  console.clear();
  if ($(this).scrollTop() >= $('#section1').position().top && $(this).scrollTop() <= $('#section2').position().top) {
    console.log("secao1");
  }
  if ($(this).scrollTop() >= $('#section2').position().top && $(this).scrollTop() <= $('#section3').position().top) {
    console.log("secao2");
  }
  if ($(this).scrollTop() >= $('#section3').position().top) {
    console.log("secao3");
  }
})
section {
  height: 500px;
  border: 1px solid red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section id="section1"></section>
<section id="section2"></section>
<section id="section3"></section>

4

you can use the getBoundingClientRect to hold the current position of an element on the screen.

//todas as paginas ocupam toda a tela.
var pages = [].slice.call(document.querySelectorAll('.page'), 0);
var checkCurrentPage = function () {
  // obtendo posição das paginas.
  var tops = pages.map(function (page) {
    var position = page.getBoundingClientRect();
    return position.top;
  });
  
  var indexUnique = tops.indexOf(0);
  if (indexUnique != -1) {
    // unica pagina sendo exibida;
    console.log([pages[indexUnique]]);
    return;
  } else {
    // obtendo as paginas que começam acima da posição atual.
    var prevs = tops.filter(function (top) {
      return top < 0;
    });
  
    var prev = pages[prevs.length - 1];
    var next = pages[prevs.length];
    console.log([ prev, next ]);
  }
}

window.addEventListener("scroll", checkCurrentPage);
window.addEventListener("resize", checkCurrentPage);
html, body {
  position: relative;
  width: 100%;
  height: 100%;
  padding: 0px;
  margin: 0px;
}

.page {
  position: relative;
  width: 100%;
  height: 100%;
}

.page1 {
  background-color: #009688
}

.page2 {
  background-color: #FF9800
}

.page3 {
  background-color: #673AB7
}
<div class="page page1">
</div>
<div class="page page2">
</div>
<div class="page page3">
</div>

if you need to know if a particular element is within the current viewport (even if only partially), then you should compare the return of the getBoundingClientRect with the window.innerWidth and window.innerHeight.

var position = page.getBoundingClientRect();
var vpWidth = window.innerWidth;
var vpHeight = window.innerHeight;

var visibleY = (position.top <= 0 && position.bottom > 0) || (position.top > 0 && position.top < vpHeight);
var visibleX = (position.left <= 0 && position.right > 0) || (position.left > 0 && position.left < vpWidth);

return visibleY && visibleX;

If the element needs it is completely visible inside the screen.:

var position = page.getBoundingClientRect();
var vpWidth = window.innerWidth;
var vpHeight = window.innerHeight;

var visibleY = position.top >= 0 && position.bottom <= vpHeight;
var visibleX = position.left >= 0 && position.right <= vpWidth;

return visibleY && visibleX;

Browser other questions tagged

You are not signed in. Login or sign up in order to post.