ipad safari: Scrollen deaktivieren und Bounce-Effekt?

126

Ich arbeite an einer browserbasierten App. Derzeit entwickle und gestalte ich sie für den iPad-Safari-Browser.

Ich suche nach zwei Dingen auf dem iPad: Wie kann ich das vertikale Scrollen für Seiten deaktivieren, die es nicht benötigen? & wie kann ich den elastischen Bounce-Effekt deaktivieren?

Adam
quelle
Beziehen Sie sich auf die folgende Antwort nur eine, die für mich funktioniert hat und aktuell ist ( stackoverflow.com/a/51176339/1979180 )
Frage

Antworten:

157

Diese Antwort gilt nicht mehr, es sei denn, Sie entwickeln für ein sehr altes iOS-Gerät ... Weitere Lösungen finden Sie hier


Antwort 2011: Für eine Web- / HTML-App, die in iOS Safari ausgeführt wird, möchten Sie so etwas wie

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

Für iOS 5 möchten Sie möglicherweise Folgendes berücksichtigen: document.ontouchmove und Scrollen unter iOS 5

Update September 2014: Einen gründlicheren Ansatz finden Sie hier: https://github.com/luster-io/prevent-overscroll . Informationen dazu und viele nützliche Tipps für Webanwendungen finden Sie unter http://www.luster.io/blog/9-29-14-mobile-web-checklist.html

Update März 2016: Dieser letzte Link ist nicht mehr aktiv - siehe https://web.archive.org/web/20151103001838/http://www.luster.io/blog/9-29-14-mobile-web-checklist .html für die archivierte Version. Vielen Dank an @falsarella für den Hinweis.

Oskar Austegard
quelle
1
Ich habe eine Webanwendung in iOS Safari ausgeführt und versucht, das Ereignis ontouchmove zu deaktivieren, aber es ist immer noch möglich, den Bounce-Effekt zu sehen, wenn dies sorgfältig durchgeführt wird. (iOS 5)
Nilesh
7
Was ist mit dem Deaktivieren des Bounce-Effekts ...?
Yuval A.
6
Das Problem bei diesem Ansatz ist, dass scrollbare Divs in Ihrem Dom nicht mehr scrollen. Abhängig von Ihrem Dom-Setup gibt es Möglichkeiten, dies zu umgehen.
Huesforalice
3
Es gibt eine Menge Leute hier, die nach dem Scrollen von Divs fragen, während sie dies verwenden. Um diese Divs scrollbar zu machen, fügen onTouchMove: function(e) { e.stopPropagation(); e.stopImmediatePropagation(); } Sie hinzu. Es verhindert, dass das Ereignis den Körper trifft, aber der Körper bleibt nicht hüpfend. Bearbeiten: Dies setzt voraus, dass Sie $ ('div'). On ('touchmove', ... onTouchMove) setzen;
Matt Kenefick
1
@OskarAustegard Der letzte Link hat bei mir nicht funktioniert, aber ich konnte den Inhalt im Webarchiv finden: web.archive.org/web/20151103001838/http://www.luster.io/blog/…
falsarella
116

Sie können auch die Position des Körpers / HTML in fest ändern:

body,
html {
  position: fixed;
}
Ben Bos
quelle
2
Dies funktionierte tatsächlich sehr gut auf iPad iOS 8.2 Safari; Kein Bounce-Effekt mehr.
Akseli Palén
3
Der beste Weg, das zu tun, den ich bisher gesehen habe
hildende
8
Funktioniert nicht, wenn Sie etwas mit Position platzieren möchten: absolut und alle Seiten auf 0 gesetzt (um ein Vollbild-Div zu erstellen) - Ihr gesamtes Dokument wird auf nichts verkleinert.
Riv
4
Die Seite springt für mich zum Anfang der Seite zurück, wenn ich diese verwende, und dann konzentriere ich mich auf eine Eingabe. Kennen Sie einen Weg, um das zu umgehen?
Julie
1
@riv Hinzufügen von Breite: 100%; Größe: 100% auf Körper und HTML hat mir geholfen.
Tim
57

Um das Scrollen in modernen mobilen Browsern zu verhindern, müssen Sie das passive: false hinzufügen. Ich hatte mir die Haare ausgezogen, damit das funktioniert, bis ich diese Lösung gefunden hatte. Ich habe dies nur an einer anderen Stelle im Internet erwähnt gefunden.

function preventDefault(e){
    e.preventDefault();
}

function disableScroll(){
    document.body.addEventListener('touchmove', preventDefault, { passive: false });
}
function enableScroll(){
    document.body.removeEventListener('touchmove', preventDefault);
}

Christopher Vickers
quelle
7
Ohne { passive: false }funktioniert es definitiv nicht !!! Willkommen auf StackOverflow Dude
Ser
2
Ich danke Ihnen für die Bereitstellung dieser Lösung!
Paul Z.
6
Dies ist die richtige Antwort. Die Erklärung finden Sie hier: developer.mozilla.org/en-US/docs/Web/API/EventTarget/… nachdem Chrome 54 touchmove standardmäßig passiv auf true gesetzt wurde, bedeutet dies, dass Vorbeugungsaufrufe ignoriert werden. Aus diesem Grund müssen Sie {passive: false} übergeben, damit der Aufruf von prepareDefault nicht ignoriert wird.
Derickito
1
Sie deklarieren die Funktion in JS - Aber wie rufen Sie diese Funktion für ein Element auf, damit sie wie vorgeschlagen funktioniert?
Ikwyl6
4
Dies funktioniert hervorragend, wenn Sie alle Arten des Bildlaufs deaktivieren möchten. Aber was ist, wenn ich nur das Scrollen auf dem Körper deaktivieren und die Möglichkeit behalten möchte, auf einem Element mit zu scrollen overflow-y: scroll? Zum Beispiel ein Modal mit einer größeren Ansichtshöhe als der Körper.
Calsal
7

Sie können dieses jQuery-Code-Snippet verwenden, um dies zu tun:

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

Dies blockiert das vertikale Scrollen und auch alle auf Ihren Seiten auftretenden Bounce-Back-Effekte.

Alessandro Incarnati
quelle
11
Dies ist kein Javascript, sondern jQuery. Sie sollten erwähnen, dass nicht jeder dieses Framework verwendet.
Inta
wie kann ich horizontal prallen oder Scroll - Stopp
fidel castro
Horizontaler Bildlauf Sie können ihn sogar mit nur CSS deaktivieren und overflow-x anwenden: hidden; zu Ihrem Hauptcontainer. Ich habe festgestellt, dass Sie in den neuesten Versionen von Safari den Bounce-Effekt jedoch nicht deaktivieren können. Dies ist eine native Funktion des Browsers auf Mobilgeräten.
Alessandro Incarnati
6
@inta Nur zu sagen, dass dies tatsächlich Javascript ist. Es ist einfach kein reines Javascript.
Ben Lorantfy
6
overflow: scroll;
-webkit-overflow-scrolling: touch;

Auf dem Container können Sie den Bounce-Effekt innerhalb des Elements festlegen

Quelle: http://www.kylejlarson.com/blog/2011/fixed-elements-and-scrolling-divs-in-ios-5/

user956584
quelle
1
Zusammen mit overflow:hiddendem <body>ist dies immer noch die beste Lösung. Wenn Sie jedoch die Tastatur öffnen oder über den unteren Bildschirmrand gleiten, funktioniert dies nicht mehr.
Fabian von Ellerts
versuchen Sie die Eingabe onfocus Überlauf entfernen
user956584
4

Ich weiß, dass dies etwas abseits der Piste liegt, aber ich habe Swiffy verwendet, um Flash in ein interaktives HTML5-Spiel umzuwandeln, und bin auf dasselbe Scrolling-Problem gestoßen, habe aber keine funktionierenden Lösungen gefunden.

Das Problem, das ich hatte, war, dass die Swiffy-Bühne den gesamten Bildschirm einnahm. Sobald sie geladen war, wurde das Dokument-Touchmove-Ereignis nie ausgelöst.

Wenn ich versuchte, dasselbe Ereignis zum Swiffy-Container hinzuzufügen, wurde es ersetzt, sobald die Bühne geladen war.

Am Ende habe ich es (ziemlich chaotisch) gelöst, indem ich das Touchmove-Ereignis auf jeden DIV innerhalb der Bühne angewendet habe. Da sich diese Divs auch ständig änderten, musste ich sie weiter überprüfen.

Dies war meine Lösung, die gut zu funktionieren scheint. Ich hoffe, es ist hilfreich für alle anderen, die versuchen, die gleiche Lösung wie ich zu finden.

var divInterval = setInterval(updateDivs,50);
function updateDivs(){
$("#swiffycontainer > div").bind(
    'touchmove',
     function(e) {
        e.preventDefault();
    }
);}
Tom
quelle
Dies deaktiviert die gesamte Schriftrolle in iPad
Fidel Castro
3

Code zum Entfernen der iPad-Safari: Deaktivieren Sie das Scrollen und den Bounce-Effekt

   document.addEventListener("touchmove", function (e) {
        e.preventDefault();
    }, { passive: false });

Wenn Sie ein Canvas- Tag im Dokument haben, wirkt sich dies manchmal auf die Benutzerfreundlichkeit des Objekts im Canvas-Bereich aus (Beispiel: Bewegung des Objekts). Fügen Sie also den folgenden Code hinzu, um das Problem zu beheben.

    document.getElementById("canvasId").addEventListener("touchmove", function (e) {
        e.stopPropagation();
    }, { passive: false });
Teju VB
quelle
2

Versuchen Sie diese JS sollutuion :

var xStart, yStart = 0; 

document.addEventListener('touchstart', function(e) {
    xStart = e.touches[0].screenX;
    yStart = e.touches[0].screenY;
}); 

document.addEventListener('touchmove', function(e) {
    var xMovement = Math.abs(e.touches[0].screenX - xStart);
    var yMovement = Math.abs(e.touches[0].screenY - yStart);
    if((yMovement * 3) > xMovement) {
        e.preventDefault();
    }
});

Verhindert standardmäßige Safari-Bildlauf- und Bounce-Gesten, ohne die Listener für Berührungsereignisse zu trennen.

Andrii Verbytskyi
quelle
Dadurch wird verhindert, dass die Web-App vollständig über das Body-Element scrollt.
MartijnICU
2

Keine der Lösungen funktioniert für mich. So mache ich es.

  html,body {
      position: fixed;
      overflow: hidden;
    }
  .the_element_that_you_want_to_have_scrolling{
      -webkit-overflow-scrolling: touch;
  }
wütende Kiwi
quelle
Ich würde das Element tun, das Sie wollen, um zu scrollen. }
Roy Segall
Ihre Antwort hat für mich für den HTML-Text funktioniert, aber ich kann "the_element_that_you_want_to_have_scrolling" nicht zum Scrollen bringen. Dieses Element ist in einigen Divs verschachtelt, die sich unter dem Körper befinden. Ist es wichtig, welche typischen Element-Tags für dieses verschachtelte Div verwendet werden, damit es gescrollt wird? Ich habe Position: relativ.
ikwyl6
1

Für diejenigen, die MyScript verwenden, die Web-App und Probleme mit dem Scrollen / Ziehen des Körpers (auf iPad und Tablets) haben, anstatt tatsächlich zu schreiben:

<body touch-action="none" unresolved>

Das hat es für mich behoben.

Miro
quelle
1

Sie können js verwenden, um das Scrollen zu verhindern:

let body = document.body;

let hideScroll = function(e) {
  e.preventDefault();
};

function toggleScroll (bool) {

  if (bool === true) {
    body.addEventListener("touchmove", hideScroll);
  } else {
    body.removeEventListener("touchmove", hideScroll);
  }
}

Und dann einfach die Funktion ausführen / stoppen, toggleScrollwenn Sie modal öffnen / schließen.

So was toggleScroll(true) / toggleScroll(false)

(Dies ist nur für iOS, unter Android funktioniert nicht)

Vlad Novikov
quelle
1

Probieren Sie diese JS-Lösung aus, die den webkitOverflowScrollingStil umschaltet . Der Trick dabei ist, dass dieser Stil deaktiviert ist, Mobile Safari zum normalen Scrollen übergeht und ein Überspringen verhindert - leider kann es das laufende Ziehen nicht abbrechen. Diese komplexe Lösung verfolgt auch, onscrollwie ein Sprung über die Oberseite ein scrollTopNegativ erzeugt, das verfolgt werden kann. Diese Lösung wurde unter iOS 12.1.1 getestet und hat einen einzigen Nachteil: Während der Beschleunigung des Bildlaufs tritt immer noch ein einzelner Übersprung auf, da das Zurücksetzen des Stils ihn möglicherweise nicht sofort abbricht.

function preventScrollVerticalBounceEffect(container) {
  setTouchScroll(true) //!: enable before the first scroll attempt

  container.addEventListener("touchstart", onTouchStart)
  container.addEventListener("touchmove", onTouch, { passive: false })
  container.addEventListener("touchend", onTouchEnd)
  container.addEventListener("scroll", onScroll)

  function isTouchScroll() {
    return !!container.style.webkitOverflowScrolling
  }

  let prevScrollTop = 0, prevTouchY, opid = 0

  function setTouchScroll(on) {
    container.style.webkitOverflowScrolling = on ? "touch" : null

    //Hint: auto-enabling after a small pause makes the start
    // smoothly accelerated as required. After the pause the
    // scroll position is settled, and there is no delta to
    // make over-bounce by dragging the finger. But still,
    // accelerated content makes short single over-bounce
    // as acceleration may not be off instantly.

    const xopid = ++opid
    !on && setTimeout(() => (xopid === opid) && setTouchScroll(true), 250)

    if(!on && container.scrollTop < 16)
      container.scrollTop = 0
    prevScrollTop = container.scrollTop
  }

  function isBounceOverTop() {
    const dY = container.scrollTop - prevScrollTop
    return dY < 0 && container.scrollTop < 16
  }

  function isBounceOverBottom(touchY) {
    const dY = touchY - prevTouchY

    //Hint: trying to bounce over the bottom, the finger moves
    // up the screen, thus Y becomes smaller. We prevent this.

    return dY < 0 && container.scrollHeight - 16 <=
      container.scrollTop + container.offsetHeight
  }

  function onTouchStart(e) {
    prevTouchY = e.touches[0].pageY
  }

  function onTouch(e) {
    const touchY = e.touches[0].pageY

    if(isBounceOverBottom(touchY)) {
      if(isTouchScroll())
        setTouchScroll(false)
      e.preventDefault()
    }

    prevTouchY = touchY
  }

  function onTouchEnd() {
    prevTouchY = undefined
  }

  function onScroll() {
    if(isTouchScroll() && isBounceOverTop()) {
      setTouchScroll(false)
    }
  }
}
Anton Baukin
quelle
1

verbesserte Antwort @Ben Bos und kommentiert von @Tim

Dieses CSS hilft dabei, Bildlauf- und Leistungsprobleme beim erneuten Rendern von CSS zu vermeiden, da sich die Position ohne Breite und Höhe geändert hat / nur wenig verzögert

body,
html {
  position: fixed;
  width: 100%; 
  height: 100%
}

Auronsan Zenx
quelle
Auf IOS13 ist dies die sauberste Lösung für mich und hat noch keine Nachteile gefunden ...
Soylent Graham
0

Für diejenigen unter Ihnen, die das Abprallen nicht loswerden möchten, sondern nur wissen möchten, wann es aufhört (z. B. um eine Berechnung der Bildschirmabstände zu starten), können Sie Folgendes tun (Container ist das überlaufende Containerelement):

    const isBouncing = this.container.scrollTop < 0 ||
    this.container.scrollTop + this.container.offsetHeight >
        this.container.scrollHeight
Phil
quelle
0

Deaktivieren Sie den Safari Bounce Scrolling-Effekt:

html,
body {
  height: 100%;
  width: 100%;
  overflow: auto;
  position: fixed;
}  
Abolfazl Baghshahi
quelle
-1

Ähnlich wie bei der wütenden Kiwi habe ich sie eher mit der Höhe als mit der Position zum Laufen gebracht:

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

.the_element_that_you_want_to_have_scrolling{
  -webkit-overflow-scrolling: touch;
}
austinh7
quelle
Als Doc wird dies den Sprung auch nach nicht deaktiviertem Momentum ermöglichen
CaSUaL
@CaSUaL Nicht sicher, was du meinst? Diese Lösung funktionierte für meinen Anwendungsfall ...
austinh7
-1

Lösung getestet, funktioniert unter iOS 12.x.

Dies ist ein Problem, auf das ich gestoßen bin:

<body> <!-- the whole body can be scroll vertically -->
  <article>

    <my_gallery> <!-- some picture gallery, can be scroll horizontally -->
    </my_gallery>

  </article>
</body>

Während ich durch meine Galerie scrolle, scrollt der Körper immer selbst (menschliches Streichen ist nicht wirklich horizontal), was meine Galerie unbrauchbar macht.

Folgendes habe ich getan, während meine Galerie mit dem Scrollen begonnen hat

var html=jQuery('html');
html.css('overflow-y', 'hidden');
//above code works on mobile Chrome/Edge/Firefox
document.ontouchmove=function(e){e.preventDefault();} //Add this only for mobile Safari

Und wenn meine Galerie das Scrollen beendet ...

var html=jQuery('html');
html.css('overflow-y', 'scroll');
document.ontouchmove=function(e){return true;}

Hoffe das hilft ~

RRTW
quelle