Impedir o “excesso de rolagem” da página

105

No Chrome para Mac, pode-se "ultrapassar" uma página (por falta de palavra melhor), como mostra a imagem abaixo, para ver "o que está por trás", semelhante ao iPad ou iPhone.

Notei que algumas páginas o têm desativado, como o Gmail e a página "nova guia".

Como posso desativar o "overscrolling"? Existem outras maneiras de controlar a "rolagem excessiva"?

insira a descrição da imagem aqui

Randomblue
fonte
1
Na verdade, estou tentando ativá- lo na página newtab, por exemplo. Tentando entender as questões envolvidas aqui.
Randomblue de
Não acho que haja uma maneira de fazer isso. É uma simples questão de ter a página longa o suficiente para permitir que o scroller seja iniciado. Além disso, considere alterar o título da sua postagem para o que você gostaria de alcançar, em vez do oposto.
Jon Egeland de

Respostas:

164

A solução aceita não estava funcionando para mim. A única maneira de fazer funcionar e ainda conseguir rolar é:

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

body {
    height: 100%;
    overflow: auto;
}
Florian Feldhaus
fonte
2
Esta solução é problemática tanto para dispositivos que não respeitam o htmlhack de estilo quanto para navegadores da web móveis que olham para o estouro total de bodydesconsiderar a altura para a qual htmlfoi definido.
funcionou em
5
Esta solução não funciona a partir do Chrome 46 para Mac. Isso evita a rolagem excessiva, mas nenhum dos elementos filho é rolável.
Daniel Bonnell
1
Então, como você pode obter o valor scrollTop que você normalmente obteria $(window).scrollTop?
Guig de
1
Nenhuma das soluções funciona para mim no Chrome 49 para mac ou Firefox 44 para mac. window.scrollYé sempre 0.
momo de
3
Funciona no Chrome, mas não no Safari.
Bretton Wade
61

No Chrome 63+, Firefox 59+ e Opera 50+, você pode fazer isso em CSS:

body {
  overscroll-behavior-y: none;
}

Isso desativa o efeito elástico no iOS mostrado na captura de tela da pergunta. No entanto, também desativa puxar para atualizar, efeitos de brilho e encadeamento de rolagem.

No entanto, você pode optar por implementar seu próprio efeito ou funcionalidade na rolagem excessiva. Se você, por exemplo, deseja desfocar a página e adicionar uma animação bacana:

<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>

Suporte de navegador

No momento em que este documento foi escrito, o Chrome 63+, Firefox 59+ e Opera 50+ suportam esse recurso. Edge apoiou publicamente enquanto o Safari é desconhecido. Acompanhe o progresso aqui e a compatibilidade do navegador atual na documentação do MDN

Mais Informações

Koslun
fonte
3
Esta é a melhor solução, na minha opinião. E simples. Aquele com todos os votos positivos pode ser problemático.
TheTC de
1
Este funcionou bem para mim.
Rajilesh Panoli
38

Uma maneira de evitar isso é usando o seguinte CSS:

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

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

Dessa forma, o corpo nunca transborda e não "pula" ao rolar na parte superior e inferior da página. O contêiner irá rolar perfeitamente seu conteúdo dentro. Isso funciona no Safari e no Chrome.

Editar

Por que o <div>elemento- extra como um invólucro pode ser útil:
a solução de Florian Feldhaus usa um pouco menos de código e também funciona bem. No entanto, pode haver uma pequena peculiaridade quando se trata de conteúdo que excede a largura da janela de visualização. Neste caso, a barra de rolagem na parte inferior da janela é movida para fora da janela de visualização pela metade e é difícil de reconhecer / alcançar. Isso pode ser evitado body { margin: 0; }se for adequado. Na situação em que você não pode adicionar este CSS, o elemento wrapper é útil, pois a barra de rolagem está sempre totalmente visível.

Encontre uma captura de tela abaixo: insira a descrição da imagem aqui

insira o nome de usuário aqui
fonte
3
Se isso funcionou uma vez, não funciona mais. No meu Chrome v37, o comportamento de deslocamento acontecerá sempre que um elemento rolar.
bbsimonbb
@ user1585345 Eu testei isso agora no Chrome 38 novamente no OS X e ainda funciona (também no Safari). Aqui está o arquivo que estou usando. Você pode testá-lo com este arquivo? Link direto para o arquivo em Sendspace.com .
insira o nome de usuário aqui
1
Eu testei com o arquivo acima, e ainda tenho o salto. Suspeito que não chegaremos ao fundo desse mistério. Chrome 37
bbsimonbb
Você não deve precisar do div wrapper extra. Verifique a resposta abaixo para uma solução melhor.
JayD3e
1
Esta solução não funciona a partir do Chrome 46 para Mac. Isso evita a rolagem excessiva, mas nenhum dos elementos filho é rolável.
Daniel Bonnell
2

Você pode usar este código para remover a touchmoveação predefinida:

document.body.addEventListener('touchmove', function(event) {
  console.log(event.source);
  //if (event.source == document.body)
    event.preventDefault();
}, false);
Daniel Prol
fonte
2
html,body {
    width: 100%;
    height: 100%;
}
body {
    position: fixed;
    overflow: hidden;
}
Cormorano71
fonte
4
Embora isso possa responder à pergunta, é melhor explicar as partes essenciais da resposta e, possivelmente, qual era o problema com o código de OPs.
pirho
Sua resposta foi sinalizada por causa de seu comprimento e conteúdo. Eu sugiro revisar. Talvez adicione detalhes adicionais.
www139
1
position: fixedé o salvador!
Nizamil Putra
1

Tente assim

body {
    height: 100vh;
    background-size: cover;
    overflow: hidden;
}
Coração da Moldávia
fonte
0

position: absolutefunciona para mim. Eu testei no Chrome 50.0.2661.75 (64-bit)e OSX.

body {
  overflow: hidden;
}

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

O efeito de salto não pode ser desabilitado, exceto a altura da página da web igual a window.innerHeight, você pode deixar seus subelementos rolar.

html {
    overflow: hidden;
}
Yibo
fonte