Enable smooth scrolling for my website in all browsers

前端 未结 6 880
醉酒成梦
醉酒成梦 2020-12-02 09:15

I\'m developing a parallax scrolling website using the Stellar and Skrollr libraries. The website behaves perfectly in Firefox because of Firefox\'s smooth scrolling feature

6条回答
  •  一向
    一向 (楼主)
    2020-12-02 10:03

    If you are Cargo cult programmer, go with jQuery. Proceed only if you are Real programmer.

    Screw jQuery.animate(), understand the math behind and pick an algorithm. Robert Penner has a nice demo, I picked EaseOutQuad.

    Read how to handle mouse wheel cross-browser style here, then do some more reading.

    In this code, I choose not to support IE 8 and older. The idea is to hook up the wheel event, prevent it (since the default behavior is jerky jump) and perform own smooth jump

    Math.easeOutQuad = function (t, b, c, d) { t /= d; return -c * t*(t-2) + b; };
    
    (function() { // do not mess global space
    var
      interval, // scroll is being eased
      mult = 0, // how fast do we scroll
      dir = 0, // 1 = scroll down, -1 = scroll up
      steps = 50, // how many steps in animation
      length = 30; // how long to animate
    function MouseWheelHandler(e) {
      e.preventDefault(); // prevent default browser scroll
      clearInterval(interval); // cancel previous animation
      ++mult; // we are going to scroll faster
      var delta = -Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail))); // cross-browser
      if(dir!=delta) { // scroll direction changed
        mult = 1; // start slowly
        dir = delta;
      }
      // in this cycle, we determine which element to scroll
      for(var tgt=e.target; tgt!=document.documentElement; tgt=tgt.parentNode) {
        var oldScroll = tgt.scrollTop;
        tgt.scrollTop+= delta;
        if(oldScroll!=tgt.scrollTop) break;
        // else the element can't be scrolled, try its parent in next iteration
      }
      var start = tgt.scrollTop;
      var end = start + length*mult*delta; // where to end the scroll
      var change = end - start; // base change in one step
      var step = 0; // current step
      interval = setInterval(function() {
        var pos = Math.easeOutQuad(step++,start,change,steps); // calculate next step
        tgt.scrollTop = pos; // scroll the target to next step
        if(step>=steps) { // scroll finished without speed up - stop animation
          mult = 0; // next scroll will start slowly
          clearInterval(interval);
        }
      },10);
    }
    
    // nonstandard: Chrome, IE, Opera, Safari
    window.addEventListener("mousewheel", MouseWheelHandler, false); 
    // nonstandard: Firefox
    window.addEventListener("DOMMouseScroll", MouseWheelHandler, false);
    })();
    

    As you can see in this demo, I prefer as little easing as possible, just to avoid jerky scrolling. Read the comments above and design your own scrolling which suits your project.

    Note: mousewheel also hooks to touchpad, but not to up/down keys. You should consider to hook key events, too.

提交回复
热议问题