简体   繁体   中英

Having Issue on Snapping Divs to the Top of Page On Scroll

I am trying to snap each div .item to the top of page on scroll when the top of the div reaches in an specific portion of page. right now this is working on div one but stuck there

 $(document).ready(function() { var windowHeight = $(window).height(), gridTop = windowHeight * .3, gridBottom = windowHeight * .6; $(window).on('scroll', function() { $('.item').each(function() { var thisTop = $(this).offset().top - $(window).scrollTop(); if ((thisTop >= gridTop) && (thisTop <= gridBottom)) { console.log($(this).data('page')); $('html, body').animate({ scrollTop: $(this).offset().top }, 700); } }); }); }); 
 body, html { width: 100%; height: 100%; } .item { border-top: 2px dashed #cccc; border-bottom: 2px dashed #cccc; height: 100vh; display: -webkit-flex; -webkit-align-items: center; display: flex; align-items: center; justify-content: center } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class='item'> <h1> Box 1 </h1> </div> <div class='item'> <h1> Box 2 </h1> </div> <div class='item'> <h1> Box 3 </h1> </div> <div class='item'> <h1> Box 4 </h1> </div> <div class='item'> <h1> Box 5 </h1> </div> <div class='item'> <h1> Box 6 </h1> </div> <div class='item'> <h1> Box 7 </h1> </div> <div class='item'> <h1> Box 8 </h1> </div> <div class='item'> <h1> Box 9 </h1> </div> 

This looks like it could be better done with Intersection Observer (IO) rather than listening to scroll event and calculating a bunch of xy coordinates and positions.

With IO you can check how elements with each other or with the viewport. Since you want to check for intersecting with the window you can exclude the root option from the options:

let options = {
  rootMargin: '0px',
  threshold: 1.0
}

let observer = new IntersectionObserver(callback, options);

next step would be to define which elements you want to watch:

let targets = document.querySelectorAll('.item');
targets.forEach(target =>{
  observer.observe(target);
});

Finally, you specify what happens in the callback function. Here you would have your check on how much of the element is actually intersecting and snap it to the top basing on your logic:

let callback = (entries, observer) => { 
  entries.forEach(entry => {
    // Each entry describes an intersection change for one observed
    // target element
  });
};

You can use this polyfill from w3c to support older browsers.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM