1

I am writing a function to check if any of my section reaches the top of window then add a class. Not sure what I am missing any help would be really appreciated.

<body>
    <section class="row"></section>
    <section class="row"></section>
    <section class="row"></section>
    <section class="row"></section>
</body>



 let _handleSectionAnimation = function() {
    let sections = document.querySelectorAll('.row');
    let currentScroll  = window.pageYOffset || document.documentElement.scrollTop;
    Array.prototype.forEach.call(sections, function(el, i) {
      console.log("element scroll top = " + el.scrollTop);
      let offsetElement = el.offsetHeight;
      if(currentScroll > offsetElement) {
        el.classList.add('animate');
      }
    });
  }
Benjamin
  • 2,612
  • 2
  • 20
  • 32
  • Explain your question. – Gufran Hasan Oct 01 '18 at 10:47
  • https://stackoverflow.com/questions/26489360/jquery-if-div-is-at-top-of-window-add-class-style-sticky-banner – chintuyadavsara Oct 01 '18 at 10:48
  • you need to compare element `offset().top` to `$(window).scrollTop()` – Arun Kumar Oct 01 '18 at 10:48
  • @ArunKumar I need it using pure javascript instead jquery – Benjamin Oct 01 '18 at 10:52
  • use element `element.offsetTop` and `window.scrolltop()` in javascript – Arun Kumar Oct 01 '18 at 10:56
  • For starters, you are checking the wrong `.scrollTop` here. What you are scrolling around in, is the `html` element, so the scrollTop property of _that_ will change. You are not scrolling content inside the individual sections, so their scrollTop will of course stay 0. To just get the position of those sections in relation to their offset parent, you want to check `.offsetTop` – misorude Oct 01 '18 at 10:58
  • updated my script in the question @misorude – Benjamin Oct 01 '18 at 11:00
  • Now it is using `currentScroll` in the if condition, a variable that doesn’t even exist anywhere else … – misorude Oct 01 '18 at 11:05
  • I added I was returning from another function in the real case missed it update here @misorude – Benjamin Oct 01 '18 at 11:09
  • 2
    @ArunKumar said, I create a simple jsfiddle. https://jsfiddle.net/5Leys4dw/. – User 28 Oct 01 '18 at 11:10
  • 1
    `offsetHeight` is still the wrong property to use - that would be the height of the section element itself. `offsetTop` is the property that tells you how far from the top corner of the offset parent, the top corner of the section element is. If your actual setup is more complex than shown above, then take into account that what the actual _offset parent_ of an element is can vary, it depends on the formatting applied. If you are unfamiliar with that, please go do some reading up on it. – misorude Oct 01 '18 at 11:12
  • @ArunKumar in your fiddle the previous section is getting added with the class not the respective section which reaches the top – Benjamin Oct 01 '18 at 11:24
  • [fiddle](https://jsfiddle.net/5Leys4dw/7/) updated one and if the height differs the adding class is not same for all the sections. – Benjamin Oct 01 '18 at 11:27
  • try to check it in actual page. Its not working in fiddle https://jsfiddle.net/5Leys4dw/8/ – Arun Kumar Oct 01 '18 at 11:37
  • I tried it with actual website problem the when the respective section reaches the top the previous elements gets added with the class active. @ArunKumar – Benjamin Oct 01 '18 at 12:45
  • just use `let force = scrollTop >= section.offsetTop` without adding `section.offsetHeight` – Arun Kumar Oct 01 '18 at 13:02
  • that works you can add to the answer section so that I can accept upvote and accept it – Benjamin Oct 01 '18 at 13:08

2 Answers2

0

(1) You need to do sth only when user is done scrolling and for that check out my(smacaz, posibly the last answer) answer here jQuery scroll() detect when user stops scrolling (2) Any visible element must be below window dot scrolltop and its bottom must be at position less than the value of window dot scrolltop + window dot height (3) position of any element can be fetched with window dot offset dot top (jquery)

Since we do sth when they're done scrolling, we don't care whether they are scrolling top to bottom or bottom to top. Assuming you have jquery the code:

function checkVisibleSection(element){
    /*
    @param element is a valid element to be selected(the sections),
    eg #section etc.
    Depending on the section width, more than one section can still be
    visible to user at a time, in any case we want the first fully visible
    */
    var el = $(element);
    var l = el.length;
    /* now get the visible part of the screen (the top boundary) */
    var top = $(window).scrollTop();
    /* now get the visible part of the screen (the bottom boundary) */
    var bot = top+($(window).height());
    /* check the first fully visible section and do sth there */
    for(var i=0;i<l;i++){
        var ofs = el.eq(i).offset().top;
        var ofh = ofs+ el.eq(i).height();
        if(ofs > top && ofs < bot){
            /* we've got the element, do anything with it here eg, below */
            el.eq(i).css({'border':'5px solid red'});
        }
    }
}

I have verified this code and it is working fine now.

smacaz
  • 148
  • 8
0

Here is the full working code and how to use the checkVisibleSection function with scroll stop:

  $(function(){
      /*
      asumming you have the following html:
      <div class="row"></div>
      <div class="row"></div>
      <div class="row"></div>
      <div class="row"></div>
      */
      var t;
      /* give it a little width and height */
      $('.row').css({'width':'80%','height':'500px','border':'1px solid black','display':'block');
      document.addEventListener('scroll',function(e){
          clearTimeout(t);
          checkScroll();
      });
      
      function checkScroll(){
          t = setTimeout(function(){
             /* they are done scrolling check which row is visible */
             checkVisibleSection('.row');
          },500); /* You can increase or reduse timer */
      }
      /* Please copy and paste the code for 
         checkVisibleSection() function here (see it below)
      */
      function checkVisibleSection(element){
          /*
          @param element is a valid element to be selected(the sections),
          eg #section etc.
          Depending on the section width, more than one section can still be
          visible to user at a time, in any case we want the first fully visible
          */
          var el = $(element);
          var l = el.length;
          /* now get the visible part of the screen (the top boundary) */
          var top = $(window).scrollTop();
          /* now get the visible part of the screen (the bottom boundary) */
          var bot = top+($(window).height());
          /* check the first fully visible section and do sth there */
          for(var i=0;i<l;i++){
              var ofs = el.eq(i).offset().top;
              var ofh = ofs+ el.eq(i).height();
              if(ofs > top && ofs < bot){
                  /* we've got the element, do anything with it here eg, below */
                  /* clear all previous operation (reset to default) to avoid duplicates */
                  el.css({'border':'1px solid black'});
                  /* start a new operation */
                  el.eq(i).css({'border':'5px solid red'});
              }
          }
      }
  });

Tested and working

smacaz
  • 148
  • 8