繁体   English   中英

在所有浏览器中为我的网站启用平滑滚动

[英]Enable smooth scrolling for my website in all browsers

我正在使用StellarSkrollr库开发一个视差滚动网站。 由于Firefox的平滑滚动功能,该网站在Firefox中表现完美,但在Chrome中,鼠标滚轮滚动很生涩,视差效果几乎被破坏。 有什么方法可以在保持性能的同时在所有浏览器中使用鼠标滚轮平滑滚动?

我找到了两个可以做你想做的jQuery插件。

Simplr-SmoothScroll //来源: SE问题

jQuery SmoothWheel

希望这可以帮助。


编辑:因为评论而导致SmoothWheel消失 - 它已经很久没有更新了,并且SmoothScroll似乎得到了很好的维护。

如果您是Cargo cult程序员 ,请使用jQuery。 只有你是真正的程序员才能继续。

拧紧jQuery.animate() ,了解背后的数学并选择算法。 Robert Penner 有一个很好的演示 ,我选择了EaseOutQuad。

了解如何处理鼠标滚轮跨浏览器的风格在这里 ,然后做一些更多的阅读

在此代码中,我选择不支持IE 8及更早版本。 想法是挂钩轮子事件,防止它(因为默认行为是跳跃的跳跃)并执行自己的平滑跳跃

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);
})();

正如您在本演示中所看到的,我更喜欢尽可能少的缓动,只是为了避免生涩的滚动。 阅读上面的评论并设计适合您项目的滚动。

注意:鼠标滚轮也可以挂钩到触摸板,但不能挂到上/下键。 你也应该考虑挂钩关键事件。

我没有太多时间,但我试着动态地编写一个(交叉浏览器和脏)平滑滚动功能。 当您停止滚动时,它会平滑减速。 您可以稍微重写一下,以满足您的需求。

试一试:

平滑滚动:

function getScrollTop(){
    if(typeof pageYOffset!= 'undefined'){
        //most browsers except IE before #9
        return pageYOffset;
    } else {
        var B = document.body; //IE 'quirks'
        var D = document.documentElement; //IE with doctype
        D = (D.clientHeight) ? D : B;
        return D.scrollTop;
    }
}

var timeouts = [];
var scrolling = false;
var scroller;
var scrollTop = getScrollTop();
var timeMs;
var alter = false;
var speed = 5;
window.onscroll = function() {
    if(alter) {
        var timeDif = new Date().getMilliseconds() - timeMs;
        speed = 5 - (timeDif / 50);
        console.log(speed);
    }
    timeMs = new Date().getMilliseconds();
    alter = !alter;
    var scrollDirection = getScrollTop() - scrollTop;
    scrollDirection = scrollDirection / Math.abs(scrollDirection);
    scrollTop = getScrollTop();
    clearTimeout(scroller);
    scroller = setTimeout(function(){
        console.log('smooth scrolling active');
        if(!scrolling) {
            timeouts.length = 0;
            scrolling = true;
            var steps = 50;
            var delay = 6;
            for(var i = 0; i < steps; i++) {
                (function(i){
                    var timeout = setTimeout(function(){
                        var perc = i / steps; 
                        var val = (perc == 1) ? 1 : (-Math.pow(2, -10 * perc) + 1); 
                        var scrollY = val * speed * scrollDirection;
                        window.scrollTo(0, getScrollTop() + scrollY);
                        setTimeout(function(){
                            if(i == (steps - 1)) scrolling = false;
                        }, steps * delay);
                    }, (i * delay));
                    timeouts.push(timeout);
                })(i);
            }
        }
    }, 50);
};

http://jsfiddle.net/ubawR/4/

对于chrome只试试这个 - https://github.com/im4aLL/chromeSmoothScroll只有1 KB

Simplr-SmoothScroll有一个错误 - 当身高不是自动时,它不适用于身体。

我发现了另一个插件,它成为我的完美解决方案。 https://github.com/inuyaksa/jquery.nicescroll

下载库( 演示 )并添加到开头

// 1. Simple mode, it styles document scrollbar:
$(document).ready(function() {  
    $("body").niceScroll();
});

由于重新涂抹和回流,基本上滚动导致生涩。 如果你可以检查并减少这些回流,你可能会获得滚动性能。

并检查onScroll事件回调函数是否执行任何昂贵的逻辑。 并且有任何内存泄漏。

Chrome开发人员工具栏堆快照对于检测内存泄漏以及查看重绘和重排非常有用。

w3schools提供了一个超级简单的JQuery代码,为所有锚标签提供平滑的滚动效果。

$(document).ready(function(){
  // Add smooth scrolling to all links
  $("a").on('click', function(event) {

    // Make sure this.hash has a value before overriding default behavior
    if (this.hash !== "") {
      // Prevent default anchor click behavior
      event.preventDefault();

      // Store hash
      var hash = this.hash;

      // Using jQuery's animate() method to add smooth page scroll
      // The optional number (800) specifies the number of milliseconds it takes to scroll to the specified area
      $('html, body').animate({
        scrollTop: $(hash).offset().top
      }, 800, function(){

        // Add hash (#) to URL when done scrolling (default click behavior)
        window.location.hash = hash;
      });
    } // End if
  });
});

这是演示: https//www.w3schools.com/jquery/tryit.asp?filename = tryjquery_eff_animate_smoothscroll

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM