Activer le défilement en douceur pour mon site Web dans tous les navigateurs

je suis en train de développer un site Web en parallaxe en utilisant les bibliothèques Stellar et Skrollr . Le site Web se comporte parfaitement dans Firefox en raison de la fonction de défilement lisse de Firefox, mais dans Chrome, défilement avec la roue de la souris est saccadé, et l'effet de parallaxe est presque ruiné. Y a-t-il un moyen d'obtenir le défilement en douceur avec la roue de la souris dans tous les navigateurs tout en maintenant les performances?

30
demandé sur Ian 2013-10-13 23:20:48

7 réponses

j'ai trouvé deux plugins jQuery qui peuvent faire ce que vous voulez.

Simplr-SmoothScroll / / Source: SE Question

jQuery Smoothhheel

Espérons que cette aide.


edit: a été supprimé Smoothhheel en raison des commentaires - il n'a pas été mis à jour en les âges, et SmoothScroll semble bien maintenu.

42
répondu Labu 2017-05-23 11:33:26

si vous êtes Cargo cult programmeur , allez avec jQuery. Procéder seulement si vous êtes programmeur réel .

Vis jQuery.animate () , comprendre les mathématiques derrière et choisir un algorithme. Robert Penner a une belle Démo , j'ai choisi EaseOutQuad.

Lire comment gérer les molette de la souris de la croix-navigateur de style ici , puis faire un peu de lire plus .

dans ce code, je choisis de ne pas soutenir IE 8 et plus. L'idée est d'accrocher la roue de l'événement, l'empêcher (le comportement par défaut est saccadé saut) et effectuer propres lisse sauter

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

comme vous pouvez voir dans cette démo , je préfère le moins d'assouplissement possible, juste pour éviter le défilement saccadé. Lisez les commentaires ci-dessus et concevez votre propre défilement qui convient à votre projet.

Remarque: la molette de la souris permet aussi de les accrocher à un pavé tactile, mais pas pour les touches haut/bas. Vous devriez envisager d'accrocher des événements clés, aussi.

11
répondu Jan Turoň 2017-05-23 11:47:36

Je n'avais pas beaucoup de temps, mais j'ai essayé d'écrire une fonctionnalité de défilement (cross browser & dirty) à la volée. Quand vous arrêtez de défiler, il décélère en douceur. Vous pouvez le réécrire un peu pour qu'il corresponde à vos besoins.

essayez ici:

Lisse de défilement:

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 /

3
répondu sjkm 2015-12-09 13:31:31

pour chrome seulement essayez ceci - https://github.com/im4aLL/chromeSmoothScroll only 1 KB

2
répondu HADI 2014-03-27 17:21:19

Simplr-SmoothScroll avoir un bug, il n'est pas le travail avec le corps, quand le corps de la hauteur n'est pas automatique.

j'ai trouvé un autre plugin et il est devenu la solution parfaite pour moi. https://github.com/inuyaksa/jquery.nicescroll

bibliothèque de téléchargement ( démo ) et ajouter au début

// 1. Simple mode, it styles document scrollbar:
$(document).ready(function() {  
    $("body").niceScroll();
});
1
répondu BigMan 2017-05-07 21:34:01

en gros, scroll cause jerky à cause des repeintes et des reflets. si vous pouvez vérifier et réduire ces reflets vous pourriez obtenir la performance de défilement.

et vérifier la fonction de rappel d'événement onScroll si son exécution toute logique coûteuse . et il y a aucune fuite de mémoire.

barre d'outils de développement de Chrome barre d'outils de tas snap shot sera utile pour détecter les fuites de mémoire et de voir repeints et reflets.

0
répondu Kishorevarma 2013-10-28 06:13:05

w3schools a fourni un code jQuery très simple pour donner à toutes les étiquettes d'ancrage un effet de défilement lisse.

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

Voici la démo: https://www.w3schools.com/jquery/tryit.asp?filename=tryjquery_eff_animate_smoothscroll

0
répondu JerryGoyal 2018-03-26 19:53:28