webentwicklung-frage-antwort-db.com.de

iOS Safari/Chrome - Unerwünschtes Scrollen beim Fokussieren einer Eingabe innerhalb des Modals

Getestet in Safari und Chrome - das gleiche Ergebnis. Ich denke, es ist ein iOS-Problem.

Dies geschieht nur, wenn sich innerhalb des Modals eine Eingabe befindet und ich auf diese Eingabe tippe. Im selben Moment wurde diese Eingabe fokussiert und die native iOS-Tastatur wird sichtbar. 

Die Seite unter dem Modal wird im selben Moment automatisch auf 50% der Höhe gescrollt. Dieses Verhalten ist völlig unerwünscht und ich habe keine Ahnung, wie Sie diese Standardfunktion von iOS verhindern können.

Demo:

 enter image description here

18
Limon Monte

Fügen Sie hier einfach eine Antwort hinzu, falls die Leute über diese Frage stolpern ( und nicht über Ihre andere Frage, die eine großartige Demo zur Veranschaulichung dieses Problems hat ).

Bei der Arbeit stehen wir vor einem ähnlichen Problem. Wie Sie bereits erwähnt haben, beträgt der Versatz immer ~ 50% der Seitenhöhe. Dies geschieht unabhängig davon, wo sich der ursprüngliche Versatz befindet.

Wenn ich in der Vergangenheit ein ähnliches "Springen" bei früheren iOS-Versionen beobachtet hatte (allerdings weniger dramatisches Springen), habe ich dies normalerweise umgangen, indem ich position: fixed (oder relative) auf die body ( ) angewendet habe, wodurch overflow: hidden richtig funktioniert ). 

Dies hat jedoch die unbeaufsichtigte Folge, dass der Benutzer an den Anfang der Seite zurückspringt, wenn er nach unten gescrollt wurde.

Wenn Sie also offen sind, dieses Problem mit einer JavaScript anzugehen, finden Sie hier einen Fix/Hack, den ich zusammengeworfen habe:

// Tapping into swal events
onOpen: function () {
  var offset = document.body.scrollTop;
  document.body.style.top = (offset * -1) + 'px';
  document.body.classList.add('modal--opened');
},
onClose: function () {
  var offset = parseInt(document.body.style.top, 10);
  document.body.classList.remove('modal--opened');
  document.body.scrollTop = (offset * -1);
}

Und wie das CSS aussieht:

.modal--opened {
  position: fixed;
  left: 0;
  right: 0;
}

Hier ist eine Abzweigung Ihrer Demoseite (aus Ihrer anderen Frage), um dies zu veranschaulichen: https://jpattishall.github.io/sweetalert2/ios-bug.html

Und für diejenigen, die eine allgemeinere Lösung suchen, können Sie beim Öffnen/Schließen eines Modals Folgendes tun:

function toggleModal() {
    var offset;
    if (document.body.classList.contains('modal--opened')) {
        offset = parseInt(document.body.style.top, 10);
        document.body.classList.remove('modal--opened');
        document.body.scrollTop = (offset * -1);
    } else {
        offset = document.body.scrollTop;
        document.body.style.top = (offset * -1) + 'px';
        document.body.classList.add('modal--opened');
    }
}

Edit: Um das "Verschieben/Nichtverschieben" von Desktops zu vermeiden, würde ich die Featureerkennung/Schnüffeln vorschlagen, um diese Funktion nur für mobile Safaris anzuwenden.

10
Jack

Um das Scrollen der Seite sowohl auf der x- als auch auf der y-Achse zu stoppen, verwenden wir das Attribut overflow: hidden; In CSS.

Also, wenn wir dies auf den Körper anwenden,

body {
    overflow: hidden !important;
}

Es sollte richtig funktionieren?

Tatsächlich funktioniert dies nicht, da Sie gerade das Scrollen von x und y für die gesamte Seite für die gesamte Zeit deaktiviert haben.

Um dies zu umgehen, können wir mit ein bisschen Javascript eine Klasse zum Body hinzufügen, wenn das Modal aktiv ist.

Zuerst müssen wir unserem Körper eine ID hinzufügen, <body id="body"> Dies ermöglicht es Javascript, den Körper zu erkennen.

Zweitens müssen wir unserem Modal eine ID hinzufügen, <div id="modal">, Damit Javascript das Modal erkennt.

<script type="text/javascript">
    function modalActive() {
        if (document.getElementById("modal").classList.contains("active")) {
            document.getElementById("body").classList.add("modal-active");
        } else {
            getElementById("modal").classList.remove("active"));
            getElementById("body").classList.remove("modal-active"));           
        }
    }
</script>

für die Schaltfläche, die das Modal startet und schließt, müssen wir ein onclick-Ereignis hinzufügen.

<button onclick="modalActive()">Click Me!</button>

Darüber hinaus müssen wir dies der CSS-Datei hinzufügen.

body {
    overflow: initial !important;
}

body.modal-active {
    overflow: hidden !important;
}

Und los geht's.

1
harryparkdotio

Also habe ich dieses Problem gelöst und auf meinem Iphone 5 getestet. Ich muss Ipad nicht überprüfen. Ich habe overflow:hidden in meiner Lösung deaktiviert. .Lösung ist es, sowohl dem HTML-Element als auch dem Body-Element grundsätzlich die Eigenschaft height und position hinzuzufügen. 

html, body {
   position:relative;
   /*overflow:hidden;*/
   height: 100%;
}

Erst wenn Sie sich auf Eingabe, Höhe und Position konzentrieren, habe ich diese Lösung bereits aus Ihrem Repo codiert. Ich schicke Ihnen eine Pull-Anfrage. Ich habe auch browserSync in Ihrem Schlupf-Setup hinzugefügt. Daher ist es jetzt einfach, auf jedem Gerät zu testen.

Prost!

EDIT: eine andere Möglichkeit, wenn die oben genannte Lösung aus irgendeinem Grund nicht funktioniert. dann,

 /*
  * @summary touch handler; will remove touch ability
  * @author yeomann
  */
  function Touchyhandler(e) {
    e.preventDefault();
  }

und später pragmatisch hinzufügen und entfernen Sie den Touch-Listener wie folgt

//to add
document.addEventListener('touchmove', Touchyhandler, false); 
//to remove   
document.removeEventListener('touchmove', Touchyhandler);

über js Lösung getestet auf IOS 9.3.2 wirkt für mich wie ein Zauber

1
Danish

Ich habe mehrere Dinge ausprobiert, die für die modulierenden Eingaben auf der HTML-Seite funktionierten. Die einfachste Lösung, die für mich funktionierte, bestand darin, dem body-Tag die folgenden Stile hinzuzufügen, wenn das Modal geöffnet ist auf der Seite.

position: fixed;
width: 100%;
0
Manohar Mankala

Ich habe dieses Problem auch erlebt. Eine kurze Erklärung ist, dass iOS Safari versucht, automatisch zu allen Eingaben zu scrollen, auf die fokussiert wird. In diesem speziellen Fall befindet sich das fokussierte Element in einem fest positionierten Element. Safari scheint es schwer zu finden, das feste Positionselement zu finden, wenn es das Element auf dem Bildschirm zentrieren möchte, wodurch der Hintergrund verschoben wird. 

Eine mögliche Lösung besteht darin, dem Eingabefeld einen touchstart-Ereignis-Listener hinzuzufügen und die aktuelle Position der Überlagerung zu berechnen, die Position auf Absolut zu ändern und die obere/linke Position zu aktualisieren, um die Überlagerung wieder an der Position zu positionieren, an der sie sich auf dem Bildschirm befand Fügen Sie schließlich einen neuen Listener blur hinzu, um die Überlagerung wieder auf die feste Position zurückzusetzen, wenn Sie den Fokus auf der Eingabe verlassen. Dies sollte das Blättern der Seite verhindern. Ich empfehle die Verwendung von touchstart, da diese vor dem focus-Ereignis ausgelöst werden sollte. In diesem Fall beginnt die Seite bereits mit dem Bildlauf. Safari sollte in der Lage sein, die absolute positionierte Überlagerung zu finden und zu zentrieren, wenn das Ereignis focus ausgelöst wird.

0
DKrautkramer

Ich bin nicht 100% sicher, aber ich könnte mir folgendes vorstellen:

Wenn die Tastatur angezeigt wird, verringert sich die Fensterhöhe, der Wert für scrollTop ist jedoch immer noch derselbe, sodass die Site zu diesem Wert springt. Sie können overflow:hidden zur body hinzufügen, wenn das Modal geöffnet ist. Dadurch wird das Scrollen "hinter" dem Modal blockiert und möglicherweise Ihr Problem gelöst.

0
Kilian So

Fügen Sie dieses Meta (Maximum-Skala = 1, Minimum-Skala = 1) hinzu, um den Bildlauf zurückzusetzen, der beim Fokussieren des Eingabefelds aufgetreten ist.

0
Pranav K