Zapobiegaj „nadmiernemu przewijaniu” strony internetowej

105

W Chrome na Maca można „przewinąć” stronę (z braku lepszego słowa), jak pokazano na poniższym zrzucie ekranu, aby zobaczyć „co się kryje”, podobnie jak na iPadzie lub iPhonie.

Zauważyłem, że niektóre strony mają tę funkcję wyłączoną, np. Gmail i strona „Nowa karta”.

Jak mogę wyłączyć „nadmierne przewijanie”? Czy są inne sposoby kontrolowania „nadmiernego przewijania”?

wprowadź opis obrazu tutaj

Randomblue
źródło
1
Na przykład próbuję go włączyć na stronie newtab. Próbuję zrozumieć związane z tym kwestie.
Randomblue
Myślę, że nie ma na to sposobu. To prosta kwestia, aby strona była wystarczająco długa, aby umożliwić rozpoczęcie przewijania. Zastanów się również nad zmianą tytułu swojego posta na to, co chciałbyś osiągnąć, zamiast na odwrót.
Jon Egeland,

Odpowiedzi:

164

Przyjęte rozwiązanie nie działało dla mnie. Jedyny sposób, w jaki sprawiłem, że działa, a jednocześnie mogę przewijać, to:

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

body {
    height: 100%;
    overflow: auto;
}
Florian Feldhaus
źródło
2
To rozwiązanie jest problematyczne zarówno dla urządzeń, które nie przestrzegają htmlhacka stylistycznego, jak i dla mobilnych przeglądarek internetowych, które patrzą na pełne przepełnienie bodynie zważając na ustawioną wysokość html.
runspired
5
To rozwiązanie nie działa od wersji Chrome 46 dla komputerów Mac. Zapobiega przewijaniu, ale żaden z elementów podrzędnych nie jest przewijalny.
Daniel Bonnell
1
Jak więc możesz uzyskać wartość scrollTop, którą zwykle otrzymujesz $(window).scrollTop?
Guig
1
Żadne z rozwiązań nie działa dla mnie w przeglądarce Chrome 49 dla komputerów Mac lub Firefox 44 dla komputerów Mac. window.scrollYjest zawsze 0.
momo
3
Działa w przeglądarce Chrome, ale nie w Safari.
Bretton Wade
61

W Chrome 63+, Firefox 59+ i Opera 50+ możesz to zrobić w CSS:

body {
  overscroll-behavior-y: none;
}

Spowoduje to wyłączenie efektu gumowania na iOS pokazanego na zrzucie ekranu pytania. Jednak wyłącza również przeciągnij, aby odświeżyć, efekty blasku i łańcuch przewijania.

Możesz jednak zdecydować się na zaimplementowanie własnego efektu lub funkcji po przewinięciu zbyt dużym. Jeśli na przykład chcesz rozmyć stronę i dodać ładną animację:

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

Wsparcie przeglądarki

Od tego momentu Chrome 63+, Firefox 59+ i Opera 50+ obsługują go. Edge publicznie ją wspierał, podczas gdy Safari jest nieznane. Śledź postępy tutaj i aktualną zgodność przeglądarek w dokumentacji MDN

Więcej informacji

Koslun
źródło
3
Moim zdaniem to najlepsze rozwiązanie. I proste. Ten z wszystkimi pozytywnymi głosami może być problematyczny.
TheTC
38

Jednym ze sposobów, aby temu zapobiec, jest użycie następującego kodu CSS:

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

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

W ten sposób treść nigdy nie jest przepełniona i nie „podskakuje” podczas przewijania na górze i na dole strony. Pojemnik doskonale przewinie swoją zawartość. Działa to w Safari i Chrome.

Edytować

Dlaczego dodatkowy <div>element jako opakowanie może być przydatny:
rozwiązanie Floriana Feldhausa używa nieco mniej kodu i również działa dobrze. Może to jednak mieć trochę dziwactwa, jeśli chodzi o zawartość, która przekracza szerokość widocznego obszaru. W tym przypadku pasek przewijania na dole okna jest odsunięty od rzutni do połowy i jest trudny do rozpoznania / sięgnięcia. Można tego uniknąć używającbody { margin: 0; } jeśli jest to odpowiednie. W sytuacji, gdy nie możesz dodać tego CSS, element wrapper jest przydatny, ponieważ pasek przewijania jest zawsze w pełni widoczny.

Znajdź zrzut ekranu poniżej: wprowadź opis obrazu tutaj

insertusernamehere
źródło
3
Jeśli to zadziałało raz, to już nie działa. W moim Chrome v37 zachowanie nadmiernej liczby wyświetleń będzie miało miejsce wszędzie tam, gdzie przewija się element.
bbsimonbb
@ user1585345 Przetestowałem to teraz w Chrome 38 ponownie na OS X i nadal działa (także w Safari). Oto plik, którego używam. Czy możesz to przetestować z tym plikiem? Bezpośredni link do pliku na sendspace.com .
insertusernamehere
1
Testowałem z powyższym plikiem i nadal mam odbicie. Podejrzewam, że nie dojdziemy do sedna tej tajemnicy. Chrome 37
bbsimonbb
Nie powinieneś potrzebować dodatkowego opakowania div. Sprawdź poniższą odpowiedź, aby uzyskać lepsze rozwiązanie.
JayD3e
1
To rozwiązanie nie działa od wersji Chrome 46 dla komputerów Mac. Zapobiega przewijaniu, ale żaden z elementów podrzędnych nie jest przewijalny.
Daniel Bonnell
2

Możesz użyć tego kodu, aby usunąć touchmovepredefiniowaną akcję:

document.body.addEventListener('touchmove', function(event) {
  console.log(event.source);
  //if (event.source == document.body)
    event.preventDefault();
}, false);
Daniel Prol
źródło
2
html,body {
    width: 100%;
    height: 100%;
}
body {
    position: fixed;
    overflow: hidden;
}
Cormorano71
źródło
4
Chociaż może to odpowiedzieć na pytanie, lepiej jest wyjaśnić podstawowe części odpowiedzi i być może na czym polegał problem z kodem PO.
pirho
Twoja odpowiedź została oznaczona ze względu na jej długość i treść. Proponuję powtórzenie. Być może dodaj dodatkowe szczegóły.
www139,
1
position: fixedjest zbawicielem!
Nizamil Putra
1

Spróbuj w ten sposób

body {
    height: 100vh;
    background-size: cover;
    overflow: hidden;
}
Moldavianheart
źródło
0

position: absolutepracuje dla mnie. Testowałem na Chrome 50.0.2661.75 (64-bit)i OSX.

body {
  overflow: hidden;
}

// position is important
#element {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  overflow: auto;
}
Tony Jin
źródło
0

Efekt odbijania nie może zostać wyłączony, z wyjątkiem tego, że wysokość strony jest równa window.innerHeight, możesz pozwolić na przewijanie elementów podrzędnych.

html {
    overflow: hidden;
}
Yibo
źródło