0

I have a simple JS that would smoothly autoscroll to another div whenever mousewheel is moved up or down.

Here's the script:

    $(document).bind('mousewheel', function(evt) {
        var delta = evt.originalEvent.wheelDelta
        if(delta < 0){
                $('html, body').animate({
                    scrollTop: $("#content-wrapper").offset().top
                }, 3000);
        }
        else {
                $('html, body').animate({
                scrollTop: $("#bgheader").offset().top
                }, 3000);
        }         
    });

My problem is that if i play for a few seconds with the mousewheel it would start scrolling here and there forever, since every move recorded is queued as additional script launch.

Is there any way to put some sort of 'cooldown' to the script? So that after using once it would become avaiable to use again in, let's say' 3 seconds? Or once the animation is finished?

4
  • 3
    Google "debouncing". Commented Jan 12, 2017 at 23:28
  • Possibly related: how to disable scrolling temporarily Commented Jan 12, 2017 at 23:32
  • Barmar - i've heard about it but as my knowledge about jquery/pure js is kinda limited i'm trying to stay away from UnderScore and other libraries, still debouncing would definitely solve this issue so thank for the contribution! Commented Jan 12, 2017 at 23:57
  • @Hodrobond i'm afraid that's not exactly what i meant, thanks for responding tho. Commented Jan 12, 2017 at 23:58

2 Answers 2

1

You can unbind the wheel event listener, and then use jQuery's .animate() callback function to re attach the event listener after it is done, like so:

function scrollHandler (event) {
    $(document).off("mousewheel.custom");
    var delta = event.originalEvent.wheelDelta
    if(delta < 0){
        $('html, body').animate({
            scrollTop: $("#content-wrapper").offset().top
        }, 3000, function () {
            // animation callback function
            $(document).on("mousewheel.custom", scrollHandler);
        }));
    }
    else {
        $('html, body').animate({
           scrollTop: $("#bgheader").offset().top
        }, 3000, function () {
          // animation callback function
          $(document).on("mousewheel.custom", scrollHandler);
        });
    }
}

// namespace the event so we can easily .off() it
$(document).on('mousewheel.custom', scrollHandler);
Sign up to request clarification or add additional context in comments.

1 Comment

This works perfect, probably it's the best way to solve it without using external libraries like UnderScore.js with it's debounce function. Thank you mhodges!
0

I've used timeouts.

var maxPoll = 3000,
    eventActive = false;

$(document).bind('mousewheel', function(evt) {
    if(eventActive) { 
        return
    } else {
        setTimeout(maxPoll, function() { eventActive = True })
    }
    var delta = evt.originalEvent.wheelDelta
    if(delta < 0){
        $('html, body').animate({
            scrollTop: $("#content-wrapper").offset().top
        }, maxPoll);
    }
    else {
        $('html, body').animate({
            scrollTop: $("#bgheader").offset().top
        }, maxPoll);
    }         
});

It's rough and it uses globals, but it basically turns off your event while the animation is running.

1 Comment

Yeah i've tried using timeouts too, but it still launches tons of script runs, they are just delayed by 3sec. Thanks for your reply tho!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.