Sergei Kobets Sergei Kobets - 8 days ago 6
jQuery Question

vertical slider with jquery

What I want to get:
When scroll down go to next div with content
When scroll up go to previous div with content
I write some code but he works with huge jumping lags and freezes...
I don't know where I made mistake. Who can help me ?

var lastScrollTop = 0;

$('.wrapper').on('scroll', function () {
var st = $('.wrapper').scrollTop();
if (st > lastScrollTop){

$(".wrapper").animate({
scrollTop: $("#one").offset().top
}, 600);

} else {

$(".wrapper").animate({
scrollTop: $("#two").offset().top
}, 600);

}
lastScrollTop = st;
});


EDIT: all must works like this one. When scroll .wrapper div up or down

-> go to next/previous div block with content

Answer

It is important to realise that the scroll event is triggered a lot during scrolling, not just on scroll end or scroll start. This means that everything inside .scroll() will also be triggered the same amount. Especially when mixing this with animations that need to happen each time, this will lead to an overhead.

Most importantly you'll want to end a previous animation when a new scroll event is triggered. To do that, use jQuery's .stop() or finish() to stop animating.

That'd look like this:

var lastScrollTop = 0;

$('.wrapper').on('scroll', function () {
   var st = $('.wrapper').scrollTop();
   if (st > lastScrollTop){

     $(".wrapper").finish().animate({
         scrollTop: $("#one").offset().top
     }, 600);

   } else {

     $(".wrapper").finish().animate({
         scrollTop: $("#two").offset().top
     }, 600);

   }
   lastScrollTop = st;
});

To further optimise you might want to limit the amount the event is triggered. This is typically done by throttling or debouncing.

In your example it'd look like this, plus some extra cleaning up:

var lastScrollTop = 0,
  wrap = $(".wrapper");

wrap.on('scroll', $.throttle(250, sectionMagnet));

function sectionMagnet() {
  var st = wrap.scrollTop();
  var el = (st > lastScrollTop) ? $("#one") : $("#two");

  wrap.finish().animate({
    scrollTop: el.offset().top
  }, 600);

  lastScrollTop = st;
}
Comments