it-swarm.com.de

Verhindern Sie iOS-Absprung, ohne die Bildlauffunktion zu deaktivieren

Ich versuche, eine Lösung zu implementieren, um den iOS-Abpralleffekt in Safari für iOS zu verhindern, wenn der Inhalt einer Webseite größer als der Darstellungsbereich ist.

Die Seite, an der ich gerade arbeite, ist sehr spezifisch in ihrer Struktur und ist dieser Seite sehr ähnlich http://new.salt.ch/

  • Die Grundstruktur ist Bootstrap-basiert.
  • Es hat eine feste Navigationsleiste an der Spitze.
  • Es hat eine Hintergrundbild-Diashow im Vollbildmodus.
  • Die Diashow hat eine Überlagerung, die am unteren Rand des Ansichtsfensters befestigt ist.
  • Es gibt ein Fußzeilenelement, das außerhalb des Arbeitsbereichs geladen wird und nur beim Scrollen des Inhalts sichtbar ist.
  • Der Inhalt blättert hinter der Navigationsleiste.
  • Der Inhalt besteht aus einem Titel, der 20 Pixel unterhalb der Navigationsleiste positioniert ist, und einer Reihe von Schaltflächen, die 20 Pixel oberhalb des Ansichtsfensters positioniert sind.
  • Beim Scrollen bewegen sich die Schaltflächen und der Titel nach oben, um die Fußzeile anzuzeigen.

Das Problem, das ich habe, ist dasselbe wie das Problem auf der Seite http://new.salt.ch/ , indem Sie beim Scrollen nach oben einen Absprungeffekt am unteren Rand des Bildschirms erhalten und der die Hintergrund und Überlagerung.

Ich habe verschiedene Lösungen ausprobiert, darunter iNoBounce.js, Nonbounce.js und ein paar andere Vorschläge, die ich zu SO gefunden habe.

Ich habe immer das gleiche Problem ... Wenn ich versuche, den Absprung zu deaktivieren, wird der gesamte Bildlauf deaktiviert. Ich vermute, das liegt daran, dass der Inhalt (außer der Fußzeile) immer so groß ist, dass der Bildlauf nicht erforderlich ist. Daher wird das Scrollen deaktiviert und die Fußzeile ist nicht mehr auf Bildlauf verfügbar.

16
Ali Samii

Dieser Code sollte den Absprung stoppen, da der HTML-Tag abspringt

html {
    height  : 100%;
    overflow: hidden;
}
body {
    height  : 100%;
    overflow: auto;
}
16
James Campbell

Wenn ich Ihre Frage richtig interpretiere, haben wir seit Jahren das gleiche Problem bei der Entwicklung plattformübergreifender mobiler Webanwendungen. Wir haben versucht, die verschiedenen proprietären Bildlauffunktionen auf jedem Gerät korrekt zu verwenden: Apple iOS, Google Android, Windows Phone, Chrome, Safari für Laptops, IE und Edge für Laptops.

jQuery Mobile versucht weiterhin, dieses Problem innerhalb der Grenzen seines Frameworks zu beheben, aber es ist zu kompliziert, da die Geräte-/Betriebssystemhersteller ständig neue Updates bereitstellen.

Ja, wir haben Lösungen für jedes einzelne Mobilgerät. Wir haben getestet, aber nicht ernsthaft darüber nachgedacht, geräteselektive Paging-Frameworks für jedes Gerät zu entwickeln, sodass wir jedes Gerät erkennen und für jedes ein etwas anderes Framework präsentieren müssen. Wahnsinnig schlechte Idee, im Grunde genommen mindestens 3 und wirklich bis zu ein Dutzend verschiedene Versionen Ihres Codes beizubehalten.

LÖSUNG: Wir hatten das größte Glück, indem wir einfach Ihre beständigen Kopf- und Fußzeilen auf Ihr Seiten-Framework gesetzt haben. Hier ist die allgemeine Lösung, bei der der Einfachheit halber Inline-Stile verwendet werden:

<html>
<head>
  <title>Fixed Header and Footer on All Mobile Web Apps</title>
  <meta name="viewport" content="user-scalable=no, initial-scale=1.0, maximum-scale=1.0" />
  <style>
    html, body { height:100%; width:100%; }
  </style>
</head>
<body>
<div style="position: fixed; height:100%; width:100%; top:0; left:0;">
  <div style="height:calc(100% - 1px); width:100%; margin-top: 60px; z-index: 1; overflow-y: scroll; -webkit-overflow-scrolling: touch;">
    [Body Content That Can Scroll if it extends beyond screen...]

  </div>
  <div style="position: absolute; top:0; left:0; width:100%; height: 60px; background:#dddddd; z-index:10;">
    [Header Content...]

  </div>
  <div style="position: absolute; bottom:0; left:0; width:100%; height: 40px; background:#cccccc; z-index:11;">
    [Footer Content...]

  </div>
</div>
</body>
</html>

Der Body kann also ein beliebiger Satz von jQuery Mobile-Seiten sein. Theoretisch kann der Körper aus nahezu jedem Inhalt eines beliebigen Rahmens bestehen.

Besonderer Hinweis, die Zeile mit der Höhe: calc (100% - 1px); ist entscheidend für die Magie.

Die scheinbar unendlichen Kombinationen oder Permutationen dieser Ausgabe sind für uns im Laufe der Jahre fast zu einem Kreuzzug geworden und haben versucht, die reinste, einfachste und universellste Lösung zu finden. Nachdem wir diesem Thema eine peinliche Anzahl von Arbeitsstunden gewidmet haben, ist dies nicht nur unsere beste Lösung, sondern auch der EINZIGE universell kompatible Ansatz, den wir gefunden haben, der es Ihnen ermöglicht, sich nur an eine einzelne Codebasis zu halten. Es wurde erfolgreich auf den neuesten Versionen von iOS, Windows Phone, Android, Chrome, Safari, PhoneGap, Firefox, IE 9-11 und Windows Edge getestet.

TAGS: Mobile App, Web-App, fester Header, fester Footer, permanenter Header, permanenter Footer, Scroll-Problem, iOS-Scroll-Bounce, Chrome Scroll-Bounce, Android Scroll-Bounce, Webkit-Scroll-Problem, Webkit-Touch-Scrolling , iOS Touch Scrolling Problem

17
Jeremy Whitt

Ich ging ein paar Antworten auf SO durch und die Dinge sahen düster aus, bis ich auf diesen Code gestoßen bin.

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

body {
  width: 100vw;
  height: 100vh;
  overflow-y: scroll;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
}

Die Stildeklarationen für body können in jedes Element eingefügt werden, für das Sie einen Bildlauf durchführen möchten. Sie können auch overflow-x und overflow-y nach Bedarf ändern. Ich persönlich brauchte es, um NICHT zu den Seiten zu scrollen, also erklärte ich es so.

update 15. September 2017: Ich musste dieses Update für ein anderes Projekt verwenden und konnte auf diese Deklarationen position: fixed und height: 100%; im Selector html verzichten. YMMV

Update 12. April 2018 (in Kommentaren erwähnt): Wenn Sie feste Elemente auf der Seite verwenden, können diese Elemente beim Scrollen visuell "verwackelt" werden.

12
Sgnl

Ich habe iNoBounce https://github.com/lazd/iNoBounce verwendet und es funktioniert perfekt!

Wenn Sie auch horizontales Scrollen zulassen müssen, gibt es eine Pull-Anforderung von santi6291 at https://github.com/lazd/iNoBounce/pull/36 , die das Problem behebt

4
Zhong Huiwen

Ich konnte die meisten Probleme lösen, die overflow: auto und overflow: scroll auf mobiler Safari unterstützen:

  • ohne die Bildlaufansicht nach dem Berühren am Anfang der Liste aufzuhängen, dann nach unten und dann nach oben zu fahren (mobile Safari führt in diesem Fall das Standard-Abprallverhalten für die gesamte Seite aus)
  • unterstützung für feste Kopfzeile/Aktionsleiste oben ohne hässliche Überlappung durch eine Bildlaufleiste

window.addEventListener('DOMContentLoaded', function () {
                        
  var atTop = true;
  var atBottom = false;

  var body = document.getElementById('fixedBody');
  body.addEventListener('touchmove', function(event){
    event.preventDefault();
  });

  body.addEventListener('touchstart', function(event){
    event.preventDefault();
  });

  body.addEventListener('touchend', function(event){
    event.preventDefault();
  });

  var scrollingDiv = document.getElementById('scrollDiv');
  if (scrollingDiv.scrollHeight <= scrollingDiv.clientHeight) {
    atBottom = true;
  }

  scrollingDiv.addEventListener('scroll', function(event){
    
    if (event.target.scrollTop === 0) {
      atTop = true;
    } else {
      atTop = false;
    }
    
    if (event.target.scrollHeight - event.target.scrollTop === event.target.clientHeight) {
      atBottom = true;
    } else {
      atBottom = false;
    }
  });
  
  var lastY = 0;
  var topLock = false;
  var bottomLock = false;
  
  scrollingDiv.addEventListener('touchmove', function(event){
    event.stopPropagation();
    var currentY = event.touches[0].clientY;
    if (currentY > lastY) {
      // moved down
      if (atTop) {
        event.preventDefault();
        topLock = true;
      }

      if (bottomLock) {
        bottomLock = false;
        // TODO: Emulate finger remove and touch again here
      }
    } else if(currentY < lastY){
      // moved top
      if (atBottom) {
        event.preventDefault();
        bottomLock = true;
      }

      if (topLock) {
        topLock = false;
        // TODO: Emulate finger remove and touch again here
      }
    }
     
    lastY = currentY;
  });

  scrollingDiv.addEventListener('touchstart', function(event){
    lastY = event.touches[0].clientY;
    event.stopPropagation();
  });

  scrollingDiv.addEventListener('touchend', function(event){
    event.stopPropagation();
  });

});
<html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"/>
</head>
<body id="fixedBody" style="overflow: hidden;">
  <div style="position: fixed; height: 64px; width:100%; top:0; left:0; background-color: green; z-index: 1;">
    Header
  </div>
  <div id="scrollDiv" style="position: absolute; width: 100%; top: 64px; bottom: 0px; overflow-y: auto; overflow-x: hidden; -webkit-overflow-scrolling: touch; background-color: white;">
    <div style="height: 150px; background-color: blue;">
      First
    </div>
    <div style="height: 150px; background-color: red;">
      Second
    </div>
    <div style="height: 150px; background-color: green;">
      Third
    </div>
    <div style="height: 150px; background-color: black;">
      Another
    </div>
  </div>
</body>
</html>

Der einzige Nachteil, den ich habe, ist, dass nichts passiert, wenn der Benutzer anfängt, sich nach unten und dann nach oben zu bewegen (erwartet: Die Liste sollte nach unten scrollen). Zumindest verhindert die Methode jedoch das "Pseudo-Scrollen" und verwirrt den Benutzer nicht.

Um dieses letzte Problem zu überwinden, muss ein Berührungsende nachgebildet und dann das Startereignis berührt werden, wenn die Richtung geändert wird (ich habe "TODO" -Kommentare eingefügt).

Update: Es ist möglich, die Verwendung des JavaScript-Code-Fixes unter iOS Cordova mit DisallowOverscroll = true und WKWebView zu vermeiden.

0
Brian Haak