web-dev-qa-db-fra.com

Activer le défilement régulier de mon site Web dans tous les navigateurs

Je développe un site Web de défilement de parallaxe en utilisant les bibliothèques Stellar et Skrollr . Le site Web se comporte parfaitement dans Firefox en raison de la fonctionnalité de défilement régulier de Firefox, mais sous Chrome, le défilement avec la molette de la souris est saccadé et l’effet de parallaxe est presque ruiné. Est-il possible d'obtenir un défilement régulier avec la molette de la souris dans tous les navigateurs tout en maintenant les performances?

31
Ian

J'ai trouvé deux plugins jQuery pouvant faire ce que vous voulez.

Simplr-SmoothScroll // Source: Question SE

jQuery SmoothWheel

J'espère que cela t'aides.


edit: Struck out SmoothWheel à cause de commentaires - il n'a pas été mis à jour depuis bien longtemps et SmoothScroll semble bien entretenu.

43
Labu

Si vous êtes programmateur culte de Cargo , utilisez jQuery. Continuez seulement si vous êtes programmeur réel .

Vissez jQuery.animate () , comprenez le calcul derrière et choisissez un algorithme. Robert Penner a une démo de Nice , j'ai choisi EaseOutQuad.

Lisez comment manipuler le style de navigation croisée avec la molette de la souris ici , puis faites un peu de lecture { plus de lecture }.

Dans ce code, j'ai choisi de ne pas prendre en charge IE 8 et les versions antérieures. L’idée est de connecter l’événement wheel, de l’empêcher (car le comportement par défaut est un saut saccadé) et d’effectuer son propre saut en douceur

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 le voir dans cette démo _, je préfère un minimum d’assouplissement, afin d’éviter un défilement saccadé. Lisez les commentaires ci-dessus et concevez votre propre défilement qui convient à votre projet.

Remarque: la molette de la souris s'accroche également au pavé tactile, mais pas aux touches haut/bas. Vous devriez également envisager d’accrocher des événements clés.

11
Jan Turoň

Je n’ai pas eu beaucoup de temps, mais j’ai essayé d’écrire une fonctionnalité de défilement régulier (multi-navigateurs). Lorsque vous arrêtez de faire défiler, il décélère en douceur. Vous pouvez le réécrire un peu pour l'adapter à vos besoins.

Essayez ici: 

Défilement lisse:

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
sjkm

pour chrome uniquement, essayez ceci - https://github.com/im4aLL/chromeSmoothScroll seulement 1 Ko

2
HADI

Simplr-SmoothScroll a un bug: il ne fonctionne pas avec body, lorsque la hauteur du corps n’est pas automatique.

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

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

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

Fondamentalement, scroll provoque des mouvements saccadés dus aux repeints et aux reflux. Si vous pouvez vérifier et réduire ces reflux, vous obtiendrez une performance de défilement. 

et vérifiez la fonction de rappel d’événement onScroll si elle exécute une logique coûteuse. et y at-il des fuites de mémoire. 

La capture instantanée de tas de la barre d'outils de développeur Chrome sera utile pour détecter les fuites de mémoire, voir les repeints et les retraits. 

0
Kishorevarma

w3schools a fourni un code JQuery super simple pour donner à toutes les balises 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
JerryGoyal