平滑滚动跨浏览器

时间:2015-12-07 21:45:01

标签: javascript scroll

我试着不通过编写我自己的scolling脚本来重新发明轮子,但我发现的所有内容都使用了jQuery(我不想用它弄乱我的代码),没有工作,没有' t支持键滚动或div滚动......没有什么是足够好的。

我在Windows 7上运行:Opera和Chrome没有平滑滚动,因此我编写的代码可以提供流畅的滚动体验。但是在默认情况下平滑滚动的资源管理器11中,我的脚本使其过于敏感。我在Mac OS上运行Chrome的朋友告诉我滚动也很流畅。

我想我的问题可以通过浏览器x操作系统列表来回答,它需要javascript滚动增强功能(我无法访问所有内容),或者通过改进我的代码来避免在不需要的浏览器下出现丑陋行为增强。

必需的功能

  • 没有jQuery
  • 平滑上/下键滚动
  • 滚动div,不仅是主窗口
  • 没有jQuery(这对我很重要,所以我提到了两次)
  • 没有MooTools,没有框架,只有原生JS(可以使用perharps Modernizr或其他精益工具)

关于代码的任何建议也很受欢迎(我知道我应该尽快使用requestAnimationFrame)

暂时,我的代码是

// easeOutQuad by Robert Penner
Math.easeOut = 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
  keyDelta = 0;
function KeyWheelHandler(e) {
  if(e.which!=38 && e.which!=40) return;
  keyDelta = e.which==38 ? -1 : 1;
  mult = 4;
  MouseWheelHandler(e);
}
function MouseWheelHandler(e) {
  e.preventDefault(); // prevent default browser scroll
  clearInterval(interval); // cancel previous animation
  ++mult; // we are going to scroll faster
  var delta = keyDelta || -Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail)));
  if(dir!=delta) { // scroll direction changed
    if(!keyDelta) mult = 1; // start slowly
    dir = delta;
  }
  // get the closest scrollable parent
  for(var tgt=e.target; tgt!=document.documentElement; tgt=tgt.parentNode) {
    var oldScroll = tgt.scrollTop;
    tgt.scrollTop+= delta;
    if(oldScroll!=tgt.scrollTop) break;
  }
  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 = 2; // current step, not less than 2, see the (t-2) in EaseOut
  interval = setInterval(function() {
    var pos = Math.easeOut(step++,start,change,steps);
    tgt.scrollTop = pos;
    if(step>=steps) { // scroll finished without speed up - stop
      mult = keyDelta = 0;
      clearInterval(interval);
    }
  },15);
}
if(window.chrome) { // Opera and Chrome
  window.addEventListener("mousewheel", MouseWheelHandler);
  //window.addEventListener("DOMMouseScroll", MouseWheelHandler); // FF
  document.documentElement.addEventListener("keydown", KeyWheelHandler);
}
})();

1 个答案:

答案 0 :(得分:0)

看起来将来(截至2015年)css smooth-scroll将解决此问题:

  

使用用户代理定义的计时功能在用户代理定义的时间段内以平滑的方式滚动滚动框。用户代理应遵循平台协议(如果有)。

     

用户代理可能会忽略此属性。 (???)

关于忽略的说明可能是浏览器mostly ignore this,但Chrome work's on it的原因,所以我希望Opera也能在以后实施。

最新版本的IE,FF和Safari在任何地方都默认顺畅滚动,所以等待可以解决这个问题。