web-dev-qa-db-fra.com

Désactiver le défilement élastique dans Safari

Je voulais juste diable le défilement élastique/effet de rebond dans Safari (OSX Lion).

J'ai trouvé la solution pour mettre overflow: hidden pour body en css, mais comme prévu seulement désactive la barre de défilement, donc si le site Web est "plus long" que l'écran, vous ne pourrez pas faire défiler!

Toutes les solutions ou astuces sont les bienvenues! Merci!

42
Fabian Pirklbauer

Vous pouvez atteindre cet objectif plus universellement en appliquant les CSS suivants:

html,
body {
  height: 100%;
  width: 100%;
  overflow: auto;
}

Ceci permet à votre contenu, quel qu’il soit, de faire défiler dans body, mais sachez que le contexte de défilement où l’événement scroll est déclenché est désormais document.body, pas window.

57
Aintaer

Si vous utilisez le overflow:hidden pirater le <body> élément, pour reprendre le comportement de défilement normal, vous pouvez positionner un <div> absolument à l'intérieur de l'élément pour faire défiler en arrière avec overflow:auto. Je pense que c'est la meilleure option, et que c'est assez facile à implémenter en utilisant seulement des CSS!

Ou, vous pouvez essayer avec jQuery:

$(document).bind(
'touchmove',
function(e) {
e.preventDefault();
}
);

Idem dans javasrcipt:

document.addEventListener(
'touchmove',
function(e) {
e.preventDefault();
},
false
);

Dernière option, cochez ipad safari: désactiver le défilement et l'effet de rebond?

14
Yisela

overflow:hidden;-webkit-overflow-scrolling:touch ne fonctionnera pas bien sur iOS safari 8.1, car l’en-tête fixe sera hors de la zone visible.

gif

Comme @Yisela le dit, le css devrait être placé sur .container(le <div> au dessous de <body>). ce qui ne semble pas un problème (au moins sur safari iOS 8.1)

gif

J'ai placé la démo sur mon blog: http://tech.colla.me/en/show/disable_elastic_scroll_on_iOS_safari

11
sunderls

Je l'avais résolu sur iPad. Essayez, si cela fonctionne aussi sur OSX.

body, html { position: fixed; }

Ne fonctionne que si vous avez un contenu plus petit que l'écran ou si vous utilisez un cadre de mise en page (Matériel angulaire dans mon cas).

Dans Angular Il est formidable de désactiver l’effet de survol de la page entière, mais les sections intérieures <md-content> peut encore défiler.

10
Martin

J'ai fait une extension pour le désactiver sur tous les sites. Pour ce faire, j'ai utilisé trois techniques: CSS pur, JS pur et hybride.

La version CSS est similaire aux solutions ci-dessus. Le JS on va un peu comme ça:

var scroll = function(e) {
    // compute state
    if (stopScrollX || stopScrollY) {
        e.preventDefault();              // this one is the key
        e.stopPropagation();
        window.scroll(scrollToX, scrollToY);
    }
}

document.addEventListener('mousewheel', scroll, false);

Le CSS one fonctionne quand on utilise position: éléments fixes et laisse le navigateur faire le défilement. Le JS one est nécessaire quand un autre JS dépend de la fenêtre (par exemple, des événements), qui serait bloquée par le précédent CSS (puisqu'elle fait défiler le corps à la place de la fenêtre) et fonctionne en arrêtant la propagation des événements sur les bords, mais nécessite synthétiser le défilement du composant non Edge; L'inconvénient est qu'il empêche certains types de défilement de se produire (ceux-ci fonctionnent avec le CSS). L'hybride essaie d'adopter une approche mixte en désactivant sélectivement le débordement directionnel (CSS) lorsque le défilement atteint un bord (JS). En théorie, il pourrait fonctionner dans les deux cas, mais pas tout à fait actuellement, car il dispose d'une marge de manœuvre à la limite.

Donc, en fonction de la mise en œuvre de votre site Web, il faut adopter l’une ou l’autre approche.

Voir ici si on veut plus de détails: https://github.com/lloeki/unelastic

5
Lloeki

Vous pouvez vérifier si les offsets de défilement sont dans les limites. S'ils vont plus loin, reculez-les.

var scrollX = 0;
var scrollY = 0;
var scrollMinX = 0;
var scrollMinY = 0;
var scrollMaxX = document.body.scrollWidth - window.innerWidth;
var scrollMaxY = document.body.scrollHeight - window.innerHeight;

// make sure that we work with the correct dimensions
window.addEventListener('resize', function () {
  scrollMaxX = document.body.scrollWidth - window.innerWidth;
  scrollMaxY = document.body.scrollHeight - window.innerHeight;
}, false);

// where the magic happens
window.addEventListener('scroll', function () {
  scrollX = window.scrollX;
  scrollY = window.scrollY;

  if (scrollX <= scrollMinX) scrollTo(scrollMinX, window.scrollY);
  if (scrollX >= scrollMaxX) scrollTo(scrollMaxX, window.scrollY);

  if (scrollY <= scrollMinY) scrollTo(window.scrollX, scrollMinY);
  if (scrollY >= scrollMaxY) scrollTo(window.scrollX, scrollMaxY);
}, false);

http://jsfiddle.net/yckart/3YnUM/

3
yckart

Aucune des solutions de débordement n'a fonctionné pour moi. Je code un effet de parallaxe avec JavaScript en utilisant jQuery. Dans Chrome et Safari sur OSX, l’effet élastique/élastique a gâché mes numéros de défilement, puisqu’il dépasse la hauteur du document et met à jour les variables de fenêtre avec des nombres hors limites. Ce que je devais faire était de vérifier si le montant défilé était plus grand que la hauteur réelle du document, comme ceci:

$(window).scroll(
    function() {
        if ($(window).scrollTop() + $(window).height() > $(document).height()) return;
        updateScroll(); // my own function to do my parallaxing stuff
    }
);
3
Gavin

Aucune des solutions ci-dessus n'a fonctionné pour moi. Cependant, au lieu de cela, j'ai enveloppé mon contenu dans une div (# outer-wrap), puis j'ai utilisé le code CSS suivant:

body {
   overflow: hidden;
}
#outer-wrap {
    -webkit-overflow-scrolling: touch;
     height: 100vh;
     overflow: auto;
}

Évidemment, cela ne fonctionne que dans les navigateurs supportant les largeurs/hauteurs des fenêtres bien sûr.

2
Owen Davey

Il existe des situations dans lesquelles les solutions CSS ci-dessus ne fonctionnent pas. Par exemple, un en-tête fixe transparent et un pied de page collant sur la même page. Vous pouvez utiliser ceci pour éviter que le safari ne bousille et ne cause des flashs sur les curseurs plein écran.

    if (navigator.userAgent.indexOf('Safari') != -1 && navigator.userAgent.indexOf('Chrome') == -1) {

        $window.bind('mousewheel', function(e) {

            if (e.originalEvent.wheelDelta / 120 > 0) {

                if ($window.scrollTop() < 2) return false;
            } 
        });

    }
1
Kieran