web-dev-qa-db-de.com

iOS 7 Safari: Das Betriebssystem bleibt 4 Sekunden lang stehen, wenn auf eine HTML-Eingabe geklickt wird

UPDATE: Das Problem scheint auf viele ausgewählte Elemente auf einer Seite zurückzuführen zu sein. Wie zufällig ist das?

Also hier ist das Problem. Wenn Sie unter iOS 7 Safari auf eine Texteingabe auf meiner Site tippen, wird die Tastatur geöffnet, das Betriebssystem wird eingefroren und für ca. 2 bis 5 Sekunden eingefroren. Anschließend wird zur Eingabe geblättert. Nachdem dies einmal erfolgt ist, geschieht dies erst wieder, wenn Sie die Seite aktualisieren. Ich habe überall nachgesehen und ja, iOS 7 Safari ist sehr fehlerhaft, aber versuchen wir mal herauszufinden, ob wir das herausfinden können. 

Hinweis: Dies ist in keinem anderen mobilen Browser oder in früheren Versionen von iOS Safari der Fall. Dies geschieht sowohl auf dem ios 7 iphone als auch auf dem ios 7 ipad.

Ich werde alles auflisten, was mein Freund und ich bisher ausprobiert haben:

  • Die Möglichkeit zum Hinzufügen von Ereignishandlern in jQuery wurde entfernt. (Hinweis: Alle unsere Event-Handler werden mit Ausnahme von Unload und Onpageshow über jQuery zugewiesen.).
  • Das jQuery-Autocomplete-Skript wurde aus den Eingaben entfernt.
  • Das gesamte JavaScript wurde aus den Eingaben entfernt.
  • Alle auf der Seite hinzugefügten Bibliotheken von Drittanbietern wurden entfernt, indem die Domänen auf dem Mac abgelehnt wurden.
  • Zurück zur vorherigen Version von jQuery. Das letzte, was wir tatsächlich verwenden konnten, bevor nichts funktionierte, war 1.7.0.
  • Zurück zur vorherigen Version der jQuery-Benutzeroberfläche.
  • Bearbeitung von Eingabeereignissen geändert, um zu delegieren und live zu sein, statt ein ("Klick")
  • Alle CSS-Klassen entfernt.
  • Alle CSS von der Seite entfernt. Hinweis: Die Reaktionszeit für das Betriebssystem war auf 1-2 Sekunden gesunken, aber immer noch aufgetreten.

Hat jemand irgendwelche Ideen?

Vielen Dank!

38
transformerTroy

(Es gibt einige etwas effektive Lösungen, siehe am Ende der Liste)

In meiner Firma leiden wir auch darunter. Wir haben ein Problem bei Apple eingereicht, haben aber Mama gehört.

Hier einige interessante Jsfiddles, um einige der Probleme zu veranschaulichen. Es scheint sich definitiv um die Anzahl der versteckten Felder zu drehen, und Textbereiche scheinen nicht betroffen zu sein.

Ich schätze aus Debugging-Bemühungen, dass es einige Funktionen gibt, die versuchen herauszufinden, ob eine Eingabe eine Kreditkarte oder eine Telefonnummer ist, oder eine spezielle Art, die das Sperrverhalten zu verursachen scheint. Dies ist jedoch nur eine Hypothese ..

Zusammenfassung:

Auf einer Seite mit einem Formular, das benannte Eingabeelemente in Containern enthält, die mit "display: none" gekennzeichnet sind, hat der erste Druck auf eine Eingabe in diesem Formular eine sehr merkliche Verzögerung (20sec-2min) zwischen der anstehenden Tastatur und der fokussierten Eingabe . Auf diese Weise wird verhindert, dass Benutzer unsere Web-App verwenden, da die Benutzeroberfläche sehr lange auf das Eingeben der Tastatur wartet. Wir haben es in verschiedenen Szenarien debugiert, um herauszufinden, was los ist, und es scheint, dass iOS7 das DOM im Vergleich zu iOS6 analysiert, was keines dieser Probleme mit sich brachte. 

Durch das Debuggen in Safari's Inspector mit angeschlossenem iPad haben wir festgestellt, dass iOS7 viel mehr Informationen über die Aktivitäten des Programms enthält, bis wir feststellen, dass _CollectFormMetaData das übergeordnete Element des Problems ist. Die Suche nach Metadaten führt zu einer massiven Abwanderung, die mit der Anzahl der versteckten Container, die Eingaben enthalten, mehr als linear zunimmt. Wir haben festgestellt, dass _isVisible und _isRenderedFormElement viel mehr aufgerufen werden, als sie vernünftigerweise sein sollten. Wenn es hilft, haben wir festgestellt, dass einige Erkennungsfunktionen in Bezug auf Kreditkarten und Adressbücher Großverbraucher waren.

Hier sind einige jsFiddles zur Veranschaulichung. Bitte zeigen Sie sie in Safari auf einem iPad mit iOS6 und dann auf einem iPad mit iOS7 an:

http://jsfiddle.net/gUDvL/20/ - Läuft gut auf beiden

http://jsfiddle.net/gUDvL/21/ - Gerade merkliche Verzögerung bei iOS 7

http://jsfiddle.net/gUDvL/22/ - Deutlichere Verzögerung bei iOS 7

http://jsfiddle.net/gUDvL/29/ - SEHR spürbare Verzögerung unter iOS 7

http://jsfiddle.net/gUDvL/30/ - Wie 29, jedoch ohne ausgeblendet - keine Verzögerung unter iOS 7

http://jsfiddle.net/gUDvL/38/ - Wie 29, jedoch weiter verschärft

http://jsfiddle.net/gUDvL/39/ - 99 verborgene Eingänge, einer sichtbar, einer separat sichtbar

http://jsfiddle.net/gUDvL/40/ - 99 verborgene Textbereiche, einer sichtbar, einer separat sichtbar

http://jsfiddle.net/gUDvL/41/ - 99 verborgene Eingaben, eine sichtbar, eine separat sichtbar, alle mit dem Attribut autocomplete = "off"

http://jsfiddle.net/gUDvL/42/ - 99 verborgene Eingänge, einer sichtbar, einer separat sichtbar. Versteckt durch Position absolut und links statt Anzeige.

http://jsfiddle.net/gUDvL/63/ - Wie gUDvL/43 /, jedoch mit Autovervollständigung, Autokorrektur, Autokapitalisierung und Rechtschreibprüfung aus

http://jsfiddle.net/gUDvL/65/ - Wie gUDvL/63/aber mit bereinigtem Einzug (scheint auf dem iPad langsamer zu sein)

http://jsfiddle.net/gUDvL/66/ Wie das gleiche wie gUDvL/65 /, jedoch ohne css erneut anstelle von DOMReady jQuery

http://jsfiddle.net/gUDvL/67/ - Wie gUDvL/66/aber mit TedGravs Fokus/Unschärfe-Technik

http://jsfiddle.net/gUDvL/68/ - Wie gUDvL/66 /, jedoch mit css-gesteuertem Texteinzug anstelle von Anzeige: Erneut sperren (spürbare Verbesserung - Reduzierung auf 2-3 Sekunden) Anfangsfokus)

http://jsfiddle.net/gUDvL/69/ - Wie gUDvL/68 /, jedoch mit TedGravs Fokus/Unschärfe neu hinzugefügt

http://jsfiddle.net/gUDvL/71/ - Wie gUDvL/66 /, jedoch mit js vor jeder Eingabe ein Legenden-Tag. (spürbare Verbesserung - Reduzierung auf 2-3 Sekunden für den anfänglichen Fokus)

<input type="text" autocomplete="off" /> (links to jsfiddle.net must be accompanied by code..)

(Beachten Sie, dass die Anbindung des iPad an einen Mac mit dem Debugger von Safari die Verzögerungen dramatisch betont.)

Schritte zum Reproduzieren:

  1. Laden Sie eines der oben genannten Jsfiddles auf das iPad
  2. Drücken Sie eine Eingabe, um den Fokus zu erhalten
  3. Beobachten Sie den Bildschirm, bis Sie tippen können

Erwartete Ergebnisse:

Erwarten Sie die Möglichkeit, tippen zu können, sobald die Tastatur geöffnet wird

Aktuelle Ergebnisse:

Achten Sie darauf, dass die Tastatur aufgeht und der Bildschirm einfriert, sodass Sie nicht für längere Zeit scrollen oder mit Safari interagieren können. Nach der Dauer wird der Fokus wie erwartet angegeben. Von da an werden keine weiteren Einfrierungen bei der Fokussierung auf Eingaben festgestellt.

tl; dr technikzusammenfassung

Insgesamt gibt es einige Korrekturen aus verschiedenen Antworten:

  • Verbergen Sie die Divs nicht mit Anzeige: Keiner - verwenden Sie etwas wie Texteinzug
  • Kurzschluss Apples Metadaten-Überprüfungslogik - viele Form-Tags oder Legend-Tags scheinen das zu tun
  • Autofokus/Unschärfe - Funktionierte nicht für mich, aber zwei Personen gaben an, dass es funktioniert hat

Verwandte Themen bei Apple:

https://discussions.Apple.com/thread/5468360

13
Jasmine Hegman

Es scheint ein Problem zu geben, wie IOS das touch-event für Eingaben und Textbereiche behandelt. Die Verzögerung wird größer, wenn das DOM größer wird. Es gibt jedoch kein Problem mit dem Fokusereignis!

Um dieses Problem zu umgehen, können Sie das Ereignis touchend überschreiben und den Fokus auf den Eingabe-/Textbereich setzen.

document.addEventListener("touchend", function (e) {  
     if (e.target.nodeName.toString().toUpperCase() == 'INPUT' || e.target.nodeName.toString().toUpperCase() == 'TEXTAREA') {  
         e.preventDefault(); 
         e.target.focus(); 
     } 
});

Dies führt jedoch zu einem neuen Problem. Sie können die Seite scrollen, während Sie den Eingabe-/Textbereich berühren. Wenn Sie jedoch loslassen, wird die Site an die ursprüngliche Position zurückgescrollt.

Um dies zu beheben, müssen Sie nur prüfen, ob ein Bildlauf aufgetreten ist, und die PrevainDefault und target.focus mit einer if - Anweisung umgeben.

Um die ursprüngliche Position festzulegen, können Sie das Ereignis touchstart verwenden.

document.addEventListener("touchstart", function (e) {
    ... //store the scrollTop or offsetHeight position and compare it in touchend event.
}

EDITIch und ein Kollege haben es ein bisschen verbessert, und es funktioniert wie ein Zauber.

var scroll = 0; 
document.addEventListener("touchstart", function (e) { 
    scroll = document.body.scrollTop; 
 });   

document.addEventListener("touchend", function (e) { 
    if (scroll == document.body.scrollTop) { 
        var node = e.target.nodeName.toString().toUpperCase(); 
        if (node == 'INPUT' || node == 'TEXTAREA' || node == 'SELECT') { 
            e.preventDefault(); 
            e.target.focus(); 
            if(node != 'SELECT') {
                var textLength = e.target.value.length; 
                e.target.setSelectionRange(textLength, textLength);
            }
        } 
    } 
}); 
7
Binke

Auch dieses Problem hatte Probleme mit einem ios-Vollbildschirm, bei dem Seiten eingefügt wurden, die ein einzelnes Eingabeelement enthielten. Es kam zu Verzögerungen von bis zu 30 Sekunden mit nur einem einzigen sichtbaren Texteingabeelement auf der Seite (und innerhalb des gesamten DOM). Bei anderen dynamisch eingefügten Seiten mit einer oder mehreren Texteingaben in derselben Webanwendung trat keine Eingabeverzögerung auf. Wie bereits erwähnt, verhält sich das Eingabefeld nach der anfänglichen Verzögerung bei nachfolgenden Fokusereignissen normal (selbst wenn die dynamische Seite, die das Eingabeelement enthält, aus dem DOM entfernt und anschließend dynamisch wiedergegeben/wieder in das DOM eingefügt wurde).

Bei einer Ahnung, basierend auf dem oben genannten Verhalten, wurde beim Laden der Seite Folgendes versucht:

$ ("# problem-input"). focus (); $ ("# problem-input"). blur ();

Während das Obige sofort ohne Verzögerung ausgeführt wird, ist das Endergebnis keine nachfolgende Verzögerung, wenn die Eingabe durch Benutzerinteraktion den Fokus erhält. Ich kann den Grund für dieses Funktionieren nicht erklären, aber es scheint konstant für meine App zu funktionieren, während andere vorgeschlagene Korrekturen fehlgeschlagen sind.

3
TedGrav

Das Hauptproblem für mich war mit versteckten Feldern. Das Formular für 10-15 Sekunden hängen lassen.

Ich habe es geschafft, mich zu bewegen, indem ich die ausgeblendeten Formularfelder außerhalb des Bildschirms positionierte.


Verstecken:

position: absolute;
left: -9999px;

Zeigen:

position: relative;
left: 0;

3
Simon McFarlane

Ich habe das gleiche freezeing Problem.

Ich bin nicht sicher, ob wir uns in derselben Situation befinden.

hier ist meine Demo: http://tedzhou.github.io/demo/ios7sucks.html

Auf meiner Seite verwende ich ein <p>-Element mit onclick-Attribut als button . Wenn der Benutzer auf die button klickt, wird die Seite in eine textarea. Wenn Sie darauf klicken, wird der Browser eingefroren.

Das Einfrieren der Zeit war relevant für die Anzahl der dom-Elemente. Auf meinen Seiten gibt es 10000 Elemente, die das Einfrieren um mehr als 10 Sekunden bewirken.

Wir können das Problem lösen, indem Sie das <p>-Element auf den echten <button> umstellen oder die Anzahl der dom-Elemente reduzieren.

ps: Entschuldigung für mein schlechtes Englisch. LOL

3
tedzhou

Für mich wurde dieses Problem dadurch verursacht, dass Benutzereingaben auf der Seite mit display:none ausgeblendet wurden.

Die Problemumgehung, die ich verwendet habe: Anstatt die Eingaben mit display:none zu verbergen, habe ich die detach()-Methode von jQuery für das Dokument verwendet, um alle nicht verwendeten Benutzereingaben "auszublenden". Dann append() die Eingänge, wenn sie benötigt wurden.

Auf diese Weise waren beim ersten Laden der Seite display:none keine Eingaben aktiviert, und es trat keine Verzögerung bei der anfänglichen Benutzerinteraktion auf.

1
Dan Bamber

Das passiert nicht nur in iOS, sondern auch in Safari 7 für MAC OS (Maverics). Ich habe festgestellt, dass das Problem auftritt, wenn Sie viele div-Tags verwenden, um Eingaben (oder Selects) innerhalb eines Formulars zu enthalten:

<div> <select>...</select> </div>
<div> <select>...</select> </div>
...

Ich habe das Layout meiner selects geändert, um ul/li und Fieldsets anstelle von divs zu verwenden, und die Freezeze-Zeit wurde drastisch reduziert.

<ul>
   <li><select>...</select></div>
   <li><select>...</select></div>
</ul>

Hier sind zwei Beispiele in jsfiddle:

5 Sekunden einfrieren

http://jsfiddle.net/k3j5v/5/

1 Sekunde einfrieren

http://jsfiddle.net/k3j5v/6/

Ich hoffe es kann jemandem helfen

1
Raphael Isidro

Das gleiche Problem ist in einer recht komplexen Anwendung mit vielen Eingaben aufgetreten. 

Angeschlossener Debugger an Safari iOS7 über USB und protokollierte UI-Ereignisse. Ich sehe ein "touchend" -Ereignis, sobald ich auf textarea (oder eine beliebige Eingabe) klicke und in 10-20 Sekunden danach, dass "click" ausgelöst wird. 

Es ist offensichtlich ein Fehler in Safary, da auf anderen Geräten wie Android oder iOS6 kein Problem mit derselben Anwendung besteht.

1
c-smile

Meine Antwort könnte etwas vom Hauptthema abweichen, aber ich bin hier nach einigem Suchen angekommen, da sich das Szenario ähnlich anfühlt.

Problem:

Mein Problem war unter iOS wie ein Lockup, aber nicht ganz, da andere Elemente auf der Seite noch interaktiv waren. Ich hatte ein <input type="search" />-Element, das beim Klicken in das Feld nicht fokussiert würde. Nach ca. 4-5 Klicks auf dem Bildschirm wird der Fokus jedoch fokussiert.

Zusätzliche Information:

Mein Projekt ist eine Hybrid-App: WebView in einer iOS-App. Die Seite wird mit Twitter Bootstrap erstellt.

Lösung:

Ich habe auch das autofocus-Attribut für das Element gesetzt. Ich habe versucht, das zu entfernen, und es hat funktioniert ... keine aufeinanderfolgenden Klicks mehr, um das Feld zu fokussieren.

0
EdwardM

Ich bin auch auf dieses Problem gestoßen, seit ich bemerkte, dass viele Leute immer noch ein Problem damit haben. Ich dachte, ich würde meine Lösung einsetzen.

Im Grunde ist meine Lösung das serverseitige Verstecken von Elementen. Meine Seite ist ASP.NET, also habe ich meine Divs mit den Eingaben mit Panels umwickelt und diese Panels als Visible false gesetzt. Auf diese Weise kann ich die Safari nicht sehen, wenn ich auf eine Eingabe klicke andere Steuerelemente, da sie serverseitig verborgen sind.

Wenn Sie diese Arbeit ein wenig wie eine clientseitige Jquery machen möchten, benötigen Sie natürlich ein automatisches Postback und ein Updatepanel. Diese Lösung erfordert zwar einen Aufwand, ist aber dennoch besser als der Versuch, einen Safarifehler zu beheben.

Hoffe das hilft.

0
misha130

iOS 12.1.1 - Dezember 2018

Hier ist eine einfache Lösung, die in meinem Fall funktioniert hat:

window.scrollTo(0,0) // an das 'Unschärfe'-Ereignis für die Eingabefelder angehängt

Zwar ist es in Bezug auf UX möglicherweise nicht ideal (insbesondere wenn Sie ein Formular mit vielen Feldern haben), es ist jedoch definitiv besser als eine Einfrierzeit von 10 Sekunden.

0
SC1000

Wir hatten das gleiche oder ein ähnliches Problem in meiner Firma. Immer wenn eine große Anzahl von Dropdown-Listen angezeigt wurde und ein Benutzer dann auf eine Dropdown-Liste geklickt hat, friert IOS 7 die Seite für ein oder zwei Minuten ein. Nach dem Auftauen würde alles von diesem Punkt an richtig funktionieren. 

Dies betraf alle Eingabetypen. Die große Anzahl von Dropdowns wurde beim ersten Laden tatsächlich ausgeblendet - der Benutzer würde die Anzeige der Dropdowns einleiten. Bis die Dropdowns angezeigt wurden - alles würde gut funktionieren. Sobald sie angezeigt wurden, konnte der Browser beim nächsten Klick, selbst bei einer Eingabe, die ordnungsgemäß funktioniert hatte, einfrieren.

Wie andere bereits bemerkt haben, scheint es, dass IOS 7 ein Problem hat, wenn die sichtbaren Eingaben im DOM analysiert werden, nachdem der Benutzer zum ersten Mal mit einer Eingabe interagiert. Wenn die Anzahl und/oder Komplexität der Elemente/Optionen/DOM höher ist, ist das Einfrieren ausgeprägter.

Da es bei der anfänglichen Benutzerinteraktion immer erstarrte, beschlossen wir, eine ausgeblendete Benutzeraktion auszulösen, sobald die Dropdown-Liste angezeigt wird. Wir haben einen transparenten Button erstellt (er konnte nicht ausgeblendet werden - er musste "angezeigt" werden) und haben einen Klick darauf gestartet, sobald der Benutzer die Dropdown-Liste geöffnet hat. Wir dachten, dies würde IOS dazu veranlassen, das DOM schneller zu analysieren, stellte jedoch fest, dass das Problem tatsächlich vollständig behoben wurde. 

0
Henry Fieger