iPhone Web App-Stop body scrolling

Tworzę aplikację webową na iPhone ' a i teraz, Od iOS5, możesz używać position: fixed; dla nagłówków itp. itd.

Chociaż to działa, jeśli przewiń w górę u góry strony, wyświetli zwykły szary obszar przez jakiś czas, zanim nie będzie można już przewijać

Przykład

Czy jest sposób, aby zatrzymać to przewijanie? Próbowałem takich rzeczy jak overflow: hidden; ale nie mogę nic znaleźć.

P. S. chcę tylko żeby jedna rzecz przestała się przewijać, mam div o nazwie # kontener, który nadal chcę mieć możliwość przewijania.

Author: alex, 2011-12-13

6 answers

Po przejrzeniu kilku rozwiązań, zacząłem tworzyć niestandardowe rozwiązanie:

Bouncefix.js

Http://jaridmargolin.github.io/bouncefix.js/

Użycie:

Bouncefix.add (el)

Zastosuj fix tak, aby dany element nie powodował już sprężystego odbicia całego ciała podczas przewijania w jego skrajnościach.

Bouncefix.remove (el)

Usuń wszystkich słuchaczy / obserwatorów odpowiedzialnych za mocowanie całego ciała bounce.

Dlaczego?

Scrollfix był dobrym początkiem, jednak zauważyłem kilka problemów:

  1. działało tylko wtedy, gdy była przewijalna zawartość. Jeśli masz pusta strona, efekt odbicia na ciele wystąpi.
  2. API nie ujawniło metody usuwania słuchaczy. Moja aplikacja będzie mieć wiele stron, i nie czułem się dobrze, aby zachować wszystkie słuchacze dołączeni, gdy użytkownik poruszał się po aplikacji.
Jak?

Używa podobnego podejście do scrollfix. Problem pojawia się, gdy jesteś w jednej z skrajności przewijania. Na touchstart patrzymy, aby zobaczyć, czy jesteśmy w górnej skrajności lub dolnej skrajności, dodając 1px, jeśli jesteśmy na górze, i usuwając 1px, jeśli jesteśmy na dole.

Niestety, ta sztuczka działa tylko wtedy, gdy jesteśmy w stanie ustawić wartość scrollTop. Jeśli zawartość nie jest jeszcze przewijalna, na przykład masz tylko 1 pozycję listy, całe ciało zostanie ponownie przewinięte. Bouncefix.js zajmie się tym wszystkim za kulisami za pomocą delegowania zdarzeń i sprawdzania przewijania przed offsetHeight za każdym razem, gdy uruchamiany jest start touchstart. W przypadku braku przewijalnej zawartości, wszystkie przewijanie na kontenerze jest blokowane za pomocą metody e. preventDefault ();

 16
Author: Jarid R. Margolin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-04 21:25:18

Co u mnie działało:

html, body, .scrollable {
    overflow: auto; 
    -webkit-overflow-scrolling: touch;
}

Plus (używając jQuery...)

$(function() {
  $(document).on("touchmove", function(evt) { evt.preventDefault() });
  $(document).on("touchmove", ".scrollable", function(evt) { evt.stopPropagation() });
});

Ważne jest, aby evt.stopPropagation() wywołanie używało delegata, ponieważ jest również przechwycone w dokumencie , ale anulowane w ostatniej sekundzie.

W efekcie to wyłapuje wszystkie touchmove zdarzenia na dokumencie, ale jeśli oryginalne zdarzenie zostało pobrane z .scrollable, po prostu stopPropagation zamiast anulować Zdarzenie.

 11
Author: Jiaaro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-09 19:04:49

Spróbuj umieścić to na górze pliku JS..

document.ontouchmove = function(event){
    event.preventDefault();
}

Spowoduje to, że w ogóle nie będziesz mógł przewijać strony, więc nie będziesz mógł zobaczyć "szarej strefy" na górze.

Źródło: zatrzymać UIWebView od" odbijania się " w pionie?

 10
Author: Ben Clayton,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 10:30:21

Update:

Ten problem był bólem dla wielu ludzi, ale tutaj jest solidne rozwiązanie stworzone przez bjrn :

Demo: http://rixman.net/demo/scroll/
I tu jest dyskusja na ten temat: https://github.com/joelambert/ScrollFix/issues/2

To zostało pierwotnie opublikowane przez ryan w odpowiedzi na moje pytanie: Prevent Touchmove default on parent but not child .

Mam nadzieję, że to pomoże niektórzy ludzie.


Oryginalna odpowiedź:

Właśnie patrzę na dokładnie ten sam problem i natknąłem się na to:

Https://github.com/joelambert/ScrollFix

Wypróbowałem go i działa prawie idealnie. Jeśli skopiujesz cały kod do wersji demonstracyjnej i wypróbujesz go na iOS, nie zobaczysz szarego tła, chyba że złapiesz czarny pasek i spróbujesz go przewinąć. Jednak powinno być dość łatwe użycie kodu, który Ben dostarczył, aby temu zapobiec happening ( preventDefault ()).

Hope that helps (it ' s definitely helped me!) will:)

 5
Author: will,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:10:50

Podobnie jak inni zasugerowali, napisałem szybką funkcję, która uderza w mój przewijany div o jeden piksel, gdy jest przewijany do góry lub dołu, aby zapobiec przeciąganiu całej strony. To jest w porządku dla mojego przewijania div, ale stałe div na mojej stronie były nadal podatne na przeciąganie strony. Przypadkowo zauważyłem, że po nałożeniu stałego div na mój przewijany div (który nie przeciągał strony z powodu mojej funkcji bump) zdarzenia przeciągania dotykowego były przekazywane przez stały div do przewijania div pod spodem i ten stały div nie był już potencjalnym przeciągaczem stron. Na tej podstawie pomyślałem, że może być możliwe użycie pełnoekranowego przewijania div w tle jako podstawy dla całej strony, aby wszystkie przeciągnięcia były przechodzone, a moje rzeczywiste elementy na górze będą bezpieczne. Fundament div musi faktycznie przewijać, więc umieściłem w nim filler div I zrobiłem go nieco większym, aby zagwarantować zwoje. I zadziałało! Poniżej znajduje się przykład wykorzystania tego pomysłu, aby zapobiec przeciąganie stron. Przepraszam, jeśli jest to oczywiste lub już opublikowane, ale nie widziałem tego nigdzie indziej i to naprawdę poprawiło moją aplikację internetową. Wypróbuj go i daj mi znać, jeśli to pomoże.

<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">

<style>
.myDiv {
    position:absolute;
    left:0;
    width:100%;
    color:white;
}

.myDiv.hidden {
    top:0;
    height:100%;
    -webkit-overflow-scrolling:touch;
    overflow-y:scroll;
}

.myDiv.title {
    top:0;
    height:30%;
    background-color:#6297BC;
}

.myDiv.scroll {
    bottom:0;
    height:70%;
    -webkit-overflow-scrolling:touch;
    overflow-y:scroll;
    background-color:#ADADAD;
}
</style>

<script>
function setup() {  
    hiddenScrollingDiv.addEventListener("scroll", preventWindowScroll);
    visibleScrollingDiv.addEventListener("scroll", preventWindowScroll);
    hiddenScrollingDiv.style.height=window.innerHeight; 
    visibleScrollingDiv.style.height=parseInt(window.innerHeight*.7)+1; 
    fillerDiv.style.height=window.innerHeight+2;
    hiddenScrollingDiv.scrollTop=1;
    visibleScrollingDiv.scrollTop=1;
}

function preventWindowScroll(evt) {
    if (evt.target.scrollTop==0) evt.target.scrollTop=1;
    else if (evt.target.scrollTop==(evt.target.scrollHeight-parseInt(evt.target.style.height))) evt.target.scrollTop=evt.target.scrollHeight-parseInt(evt.target.style.height)-1;
}
</script>
</head>

<body onload="setup()">
<div id="hiddenScrollingDiv" class="myDiv hidden"><div id="fillerDiv"></div></div>
<div id="visibleTitleDiv" class="myDiv title"><br><center>Non-scrolling Div</center></div>

<div id="visibleScrollingDiv" class="myDiv scroll">
<ul>
    <li style="height:50%">Scrolling Div</li>
    <li style="height:50%">Scrolling Div</li>
    <li style="height:50%">Scrolling Div</li>
</ul>
</div>

</body>
</html>
 1
Author: Shawn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-22 21:51:09

Zaproponowano poprzednie rozwiązanie:

document.ontouchmove = function(event){
    event.preventDefault();
}

To jednak również zatrzymuje przewijanie dla elementu zainteresowania.

Aby to przezwyciężyć, można zrobić:

  1. Detect when the top/bottom of a element of interest (np. modal) został przewinięty do.
  2. jeśli przewinięcie do dołu, użyj powyższej techniki preventDefault dla zdarzenia ontouchmove, ale tylko wtedy, gdy użytkownik spróbuje przewinąć dalej w dół.
  3. jeśli użytkownik spróbuje przewinąć w górę, nie preventDefault już nie.
  4. odwrotnie, jeśli góra jest przewijana do.

Oto kod źródłowy do implementacji powyższej logiki.

Pakiet npm można również pobrać dla wygody (testowany z vanilla JS/React na iOS mobile/desktop safari oraz Android/Desktop Chrome).

Checkout https://medium.com/jsdownunder/locking-body-scroll-for-all-devices-22def9615177 dla bardziej wyjaśnienia różnych podejść.

 0
Author: Will Po,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-14 11:10:06