How do you know if the scroll position is on top of a section?

4

I do not know if it was clear, but I'll explain, I have several sections on my site, and when I scroll I wanted to do some Javascript effects, as I do to know when exactly the user will be viewing the div, as in Scroll Spy Boostrap? I tried the pageYoffset, but the measurements vary by resolution.

    
asked by anonymous 02.06.2017 / 14:23

2 answers

4

You can use getBoundingClientRect to attach the current position of an element to 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 getBoundingClientRect with 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 you need 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;
    
02.06.2017 / 15:01
3

Just check if scrollTop () is greater than or equal to position().top of the section you want to check, scrollTop() returns the current vertical position of the scroll bar, 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 section of interest and the beginning of the next section , ie ensuring that it is about the correct section.

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

Here is a sample snippet:

$(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><sectionid="section1"></section>
<section id="section2"></section>
<section id="section3"></section>
    
02.06.2017 / 14:34