javascriptjqueryhtmlanchoranchor-scroll

Auto-Scroll to next anchor at Mouse-wheel


I have 5 anchors on my html page. Is there any way that the page scrolls automatically to the next anchor (#) by a single Mouse-wheel scroll? Is there a way that it happens regardless of the anchor's name? just to the next anchor.


Solution

  • This works in Chrome, IE, Firefox, Opera, and Safari:

    (function() {
      var delay = false;
    
      $(document).on('mousewheel DOMMouseScroll', function(event) {
        event.preventDefault();
        if(delay) return;
    
        delay = true;
        setTimeout(function(){delay = false},200)
    
        var wd = event.originalEvent.wheelDelta || -event.originalEvent.detail;
    
        var a= document.getElementsByTagName('a');
        if(wd < 0) {
          for(var i = 0 ; i < a.length ; i++) {
            var t = a[i].getClientRects()[0].top;
            if(t >= 40) break;
          }
        }
        else {
          for(var i = a.length-1 ; i >= 0 ; i--) {
            var t = a[i].getClientRects()[0].top;
            if(t < -20) break;
          }
        }
        if(i >= 0 && i < a.length) {
          $('html,body').animate({
            scrollTop: a[i].offsetTop
          });
        }
      });
    })();
    

    Fiddle at http://jsfiddle.net/t6LLybx8/728/

    How it works

    To monitor the mouse wheel in most browsers, use $(document).on('mousewheel'). Firefox is the oddball, and it requires $(document).on('DOMMouseScroll').

    To get the direction of the mouse wheel (up or down), use event.originalEvent.wheelDelta. Again, Firefox is the oddball, and you have to use -event.originalEvent.detail.

    If the direction is a negative number, you're scrolling down the page. In that case, loop through each tag beginning with the first, until its first getClientRects() top is >= 40. (I used 40, in case the browser adds a default margin at the top of the viewport.)

    If the direction is a positive number, you're scrolling up the page. In that case, loop through each tag beginning with the last, until its first getClientRects() top is < -20. (I used -20 to ensure we move up the page.)

    The delay variable prevents the mouse wheel from scrolling too quickly. The entire function is wrapped in a closure, so delay remains a private variable.