Empêcher le «défilement excessif» de la page Web

105

Dans Chrome pour Mac, on peut «faire défiler» une page (faute d'un meilleur mot), comme le montre la capture d'écran ci-dessous, pour voir «ce qu'il y a derrière», similaire à l'iPad ou à l'iPhone.

J'ai remarqué que certaines pages l'ont désactivé, comme gmail et la page "nouvel onglet".

Comment puis-je désactiver le «défilement excessif»? Existe-t-il d’autres moyens de contrôler le «défilement excessif»?

entrez la description de l'image ici

Randomblue
la source
1
J'essaie en fait de l' activer sur la page newtab, par exemple. Essayer de comprendre les problèmes impliqués ici.
Randomblue
Je ne pense pas qu'il y ait moyen de faire ça. Il suffit de faire en sorte que la page soit suffisamment longue pour permettre au défilement de démarrer. Pensez également à changer le titre de votre message en ce que vous souhaitez réaliser au lieu du contraire.
Jon Egeland

Réponses:

164

La solution acceptée ne fonctionnait pas pour moi. La seule façon dont je l'ai fait fonctionner tout en étant capable de faire défiler est:

html {
    overflow: hidden;
    height: 100%;
}

body {
    height: 100%;
    overflow: auto;
}
Florian Feldhaus
la source
2
Cette solution est problématique à la fois pour les appareils qui ne respectent pas le htmlhack de style et pour les navigateurs Web mobiles qui regardent le débordement complet de bodyne pas tenir compte de la hauteur à laquelle a htmlété définie.
runspired
5
Cette solution ne fonctionne pas à partir de Chrome 46 pour Mac. Il empêche le sur-défilement mais aucun des éléments enfants ne peut faire défiler.
Daniel Bonnell
1
Ensuite, comment pouvez-vous obtenir la valeur scrollTop que vous obtiendrez habituellement $(window).scrollTop?
Guig
1
Aucune des deux solutions ne fonctionne pour moi sur Chrome 49 pour mac ou Firefox 44 pour mac. window.scrollYest toujours 0.
momo
3
Fonctionne pour Chrome, mais pas Safari.
Bretton Wade
61

Dans Chrome 63+, Firefox 59+ et Opera 50+, vous pouvez le faire en CSS:

body {
  overscroll-behavior-y: none;
}

Cela désactive l'effet de bande élastique sur iOS montré dans la capture d'écran de la question. Cependant, il désactive également le pull-to-refresh, les effets d'éclat et le chaînage de défilement.

Vous pouvez cependant choisir d'implémenter votre propre effet ou fonctionnalité lors du défilement excessif. Si vous souhaitez par exemple flouter la page et ajouter une animation soignée:

<style>
  body.refreshing #inbox {
    filter: blur(1px);
    touch-action: none; /* prevent scrolling */
  }
  body.refreshing .refresher {
    transform: translate3d(0,150%,0) scale(1);
    z-index: 1;
  }
  .refresher {
    --refresh-width: 55px;
    pointer-events: none;
    width: var(--refresh-width);
    height: var(--refresh-width);
    border-radius: 50%; 
    position: absolute;
    transition: all 300ms cubic-bezier(0,0,0.2,1);
    will-change: transform, opacity;
    ...
  }
</style>

<div class="refresher">
  <div class="loading-bar"></div>
  <div class="loading-bar"></div>
  <div class="loading-bar"></div>
  <div class="loading-bar"></div>
</div>

<section id="inbox"><!-- msgs --></section>

<script>
  let _startY;
  const inbox = document.querySelector('#inbox');

  inbox.addEventListener('touchstart', e => {
    _startY = e.touches[0].pageY;
  }, {passive: true});

  inbox.addEventListener('touchmove', e => {
    const y = e.touches[0].pageY;
    // Activate custom pull-to-refresh effects when at the top of the container
    // and user is scrolling up.
    if (document.scrollingElement.scrollTop === 0 && y > _startY &&
        !document.body.classList.contains('refreshing')) {
      // refresh inbox.
    }
  }, {passive: true});
</script>

Prise en charge du navigateur

Au moment d'écrire ces lignes, Chrome 63+, Firefox 59+ et Opera 50+ le prennent en charge. Edge l'a pris en charge publiquement alors que Safari est un inconnu. Suivez les progrès ici et la compatibilité actuelle du navigateur dans la documentation MDN

Plus d'information

Koslun
la source
3
C'est la meilleure solution, à mon avis. Et simple. Celui avec tous les votes positifs peut être problématique.
TheTC
38

Une façon d'éviter cela consiste à utiliser le CSS suivant:

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

body > div {
    height: 100%;
    overflow: scroll;
    -webkit-overflow-scrolling: touch;
}

De cette façon, le corps n'a jamais de débordement et ne «rebondira» pas lors du défilement en haut et en bas de la page. Le conteneur fera parfaitement défiler son contenu à l'intérieur. Cela fonctionne dans Safari et dans Chrome.

Éditer

Pourquoi cet <div>élément supplémentaire comme wrapper pourrait être utile:
la solution de Florian Feldhaus utilise un peu moins de code et fonctionne bien aussi. Cependant, cela peut avoir une petite bizarrerie, quand il s'agit de contenu qui dépasse la largeur de la fenêtre. Dans ce cas, la barre de défilement en bas de la fenêtre est déplacée hors de la fenêtre à mi-chemin et est difficile à reconnaître / atteindre. Cela peut être évité body { margin: 0; }si cela est approprié. Dans le cas où vous ne pouvez pas ajouter ce CSS, l'élément wrapper est utile car la barre de défilement est toujours entièrement visible.

Trouvez une capture d'écran ci-dessous: entrez la description de l'image ici

insérer le nom d'utilisateur ici
la source
3
Si cela a fonctionné une fois, cela ne fonctionne plus. Dans mon Chrome v37, le comportement de survol se produira partout où un élément défile.
bbsimonbb
@ user1585345 Je l'ai testé à nouveau dans Chrome 38 sous OS X et cela fonctionne toujours (également dans Safari). Voici le fichier que j'utilise. Pouvez-vous le tester avec ce fichier? Lien direct vers le fichier sur sendpace.com .
insérer
1
J'ai testé avec le fichier ci-dessus et j'ai toujours le rebond. Je soupçonne que nous n'irons pas au fond de ce mystère. Chrome 37
bbsimonbb
Vous ne devriez pas avoir besoin du div wrapper supplémentaire. Vérifiez la réponse ci-dessous pour une meilleure solution.
JayD3e
1
Cette solution ne fonctionne pas à partir de Chrome 46 pour Mac. Il empêche le sur-défilement mais aucun des éléments enfants ne peut faire défiler.
Daniel Bonnell
2

Vous pouvez utiliser ce code pour supprimer une touchmoveaction prédéfinie:

document.body.addEventListener('touchmove', function(event) {
  console.log(event.source);
  //if (event.source == document.body)
    event.preventDefault();
}, false);
Daniel Prol
la source
2
html,body {
    width: 100%;
    height: 100%;
}
body {
    position: fixed;
    overflow: hidden;
}
Cormorano71
la source
4
Bien que cela puisse répondre à la question, il est préférable d'expliquer les parties essentielles de la réponse et éventuellement quel était le problème avec le code OP.
pirho
Votre réponse a été signalée en raison de sa longueur et de son contenu. Je suggère de réviser. Peut-être ajouter des détails supplémentaires.
www139
1
position: fixedest le sauveur!
Nizamil Putra le
1

Essayez de cette façon

body {
    height: 100vh;
    background-size: cover;
    overflow: hidden;
}
Moldavianheart
la source
0

position: absolutetravaille pour moi. J'ai testé sur Chrome 50.0.2661.75 (64-bit)et OSX.

body {
  overflow: hidden;
}

// position is important
#element {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  overflow: auto;
}
Tony Jin
la source
0

L'effet de rebond ne peut pas être désactivé sauf que la hauteur de la page Web est égale à window.innerHeight, vous pouvez laisser vos sous-éléments défiler.

html {
    overflow: hidden;
}
Yibo
la source