-1

I want to set top:0(offset:0) when image come in viewport on single scroll (like on every single scroll next image set to top 0 of image position or offset 0 of image) after completing scrolling all image, continue scrolling the page. Any one have any idea, JavaScript code for this?

Here is link for try out JsFiddle

<div class="main-div">
 <div class="sticky-div">
   <img src="https://images.unsplash.com/photo-1601140958046-ce3c75269438?ixlib=rb- 
   1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2134&q=80" />
 </div>
 <div class="sticky-div">
   <img src="https://images.unsplash.com/photo-1559642147-97be7782c7b3?ixlib=rb- 
   1.2.1&auto=format&fit=crop&w=700&q=80">
</div>
<div class="sticky-div">
  <img src="https://images.unsplash.com/photo-1527435292159-ba44021581fa?ixlib=rb- 
  1.2.1&auto=format&fit=crop&w=634&q=80">
</div>
</div>

.main-div {
   box-sizing: border-box;
}

.sticky-div {
   position: sticky;
   top:0;
    height:100vh;
}    


if($(window).width() >= 1024){

(function($) {
var selector = ".home-product-slider .product-item";

var $slides = $(selector);

var currentSlide = 0;
var isAnimating = false;

var stopAnimation = function() {
  setTimeout(function() {
    isAnimating = false;
  }, );
};

var bottomIsReached = function($elem) {
  var rect = $elem[0].getBoundingClientRect();
  return rect.bottom <= $(window).height();
};

var topIsReached = function($elem) {
  var rect = $elem[0].getBoundingClientRect();
  return rect.top >= 0;
};

document.addEventListener(
  "wheel",
  function(event) {
    var $currentSlide = $($slides[currentSlide]);

    if (isAnimating) {
      event.preventDefault();
      return;
    }

    var direction = -event.deltaY;

    if (direction < 0) {
      // next
      if (currentSlide + 1 >= $slides.length) return;
      if (!bottomIsReached($currentSlide)) return;
      event.preventDefault();
      currentSlide++;
      var $slide = $($slides[currentSlide]);
      var offsetTop = $slide.offset().top;
      isAnimating = false;
      $("html, body").animate(
        {
          scrollTop: offsetTop,
          behavior: 'smooth' 

        },
        stopAnimation
      );
    } else {
      // back
      if (currentSlide - 1 < 0) return;
      if (!topIsReached($currentSlide)) return;
      event.preventDefault();
      currentSlide--;
      var $slide = $($slides[currentSlide]);
      var offsetTop = $slide.offset().top;
      isAnimating = false;
      $("html, body").animate(
        {
    //             scrollTop: offsetTop
        },
        stopAnimation
      );
    }
    { passive: false }
   },

  );
 })(jQuery);
    //home page slider script end here

  }
Taskmaster
  • 78
  • 1
  • 8

1 Answers1

1

You're looking for scroll snapping. On the container that controls the scrolling set the scroll-snap-type: y mandatory rule. Here you say that there should be snapped in the y axis and that the snap should be honored without exceptions.

On the elements that you want snapped, use the scroll-snap-align property. Set this to start indicating that the start of the element that scrolls into view should fall on the snap grid.

Do beware, the combination of position: sticky and scroll snapping could lead to buggy behavior on Safari iOS. source

html,
body {
  margin: 0;
  overflow: hidden;
}

.main-div {
  box-sizing: border-box;
  width: 1000px;
  height: 100vh;
  max-width: 100%;
  overflow-y: auto;
  scroll-snap-type: y mandatory;
}

.sticky-div {
  position: sticky;
  top: 0px;
  width: 100%;
  max-height: 100%;
  height: 750px;
  scroll-snap-align: start;
}

img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
<div class="main-div">
  <div class="sticky-div">
    <img src="https://images.unsplash.com/photo-1601140958046-ce3c75269438?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2134&q=80" />
  </div>
  <div class="sticky-div">
    <img src="https://images.unsplash.com/photo-1559642147-97be7782c7b3?ixlib=rb-1.2.1&auto=format&fit=crop&w=700&q=80">
  </div>
  <div class="sticky-div">
    <img src="https://images.unsplash.com/photo-1527435292159-ba44021581fa?ixlib=rb-1.2.1&auto=format&fit=crop&w=634&q=80">
  </div>
  <div class="sticky-div">
    <img src="https://images.unsplash.com/photo-1601140958046-ce3c75269438?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2134&q=80" />
  </div>
  <div class="sticky-div">
    <img src="https://images.unsplash.com/photo-1559642147-97be7782c7b3?ixlib=rb-1.2.1&auto=format&fit=crop&w=700&q=80">
  </div>
  <div class="sticky-div">
    <img src="https://images.unsplash.com/photo-1527435292159-ba44021581fa?ixlib=rb-1.2.1&auto=format&fit=crop&w=634&q=80">
  </div>
</div>
Emiel Zuurbier
  • 19,095
  • 3
  • 17
  • 32
  • Yes, its working sticky properly but image set offset 0 after 2 3 mouse wheel scroll but I want it offset 0 on single scroll for every image, Right now image offset:0 or top:0 set after some multiple scroll. Have you any idea how to set offset 0 on single scroll for every image on not when the image naturally comes on top @Emiel Zuurbier – Taskmaster Sep 28 '20 at 03:49
  • Ah, I didn't understand your issue at first, but sure. You can do this with scroll snapping. Checkout the edited answer above. You do need to change the element that scrolls, though. – Emiel Zuurbier Sep 28 '20 at 05:09