iPad Web App: Virtuelle Tastatur mithilfe von JavaScript in Safari erkennen?

147

Ich schreibe eine Web-App für das iPad ( keine reguläre App Store-App - sie wurde mit HTML, CSS und JavaScript geschrieben). Da die Tastatur einen großen Teil des Bildschirms ausfüllt, ist es sinnvoll, das Layout der App so zu ändern, dass es dem verbleibenden Platz entspricht, wenn die Tastatur angezeigt wird. Ich habe jedoch keine Möglichkeit gefunden, festzustellen, wann oder ob die Tastatur angezeigt wird.

Meine erste Idee war anzunehmen, dass die Tastatur sichtbar ist, wenn ein Textfeld den Fokus hat. Wenn jedoch eine externe Tastatur an ein iPad angeschlossen ist, wird die virtuelle Tastatur nicht angezeigt, wenn ein Textfeld den Fokus erhält.

In meinen Experimenten hatte die Tastatur auch keinen Einfluss auf die Höhe oder Bildlaufhöhe eines der DOM-Elemente, und ich habe keine proprietären Ereignisse oder Eigenschaften gefunden, die angeben, ob die Tastatur sichtbar ist.

LKM
quelle
1
Hm, interessantes Problem. Versuchen Sie, die Objekte von "window" auf der Safari des iPad zu durchlaufen, um festzustellen, ob spezielle Objekte für die Tastaturunterstützung vorhanden sind.
David Murdoch
@ David, das nicht funktioniert, die Tastatur ist kein Javascript "Fenster".
Kennytm
2
@ KennyTM. Duh. Möglicherweise befindet sich jedoch in einem der Fensterobjekte ein Flag, das sich auf die Bildschirmtastaturanzeige bezieht. Es ist einen Versuch wert.
David Murdoch
1
Das habe ich versucht. Ich habe leider nichts gefunden. Vergleichen Sie außerdem alle Fenstereigenschaften drei Ebenen tief vor und nach dem Anzeigen der Tastatur. Keiner der Unterschiede schien als Indikatoren für die Tastatur relevant zu sein.
LKM
3
Gibt es eine neuere Antwort darauf?
Fraxture

Antworten:

54

Ich habe eine Lösung gefunden, die funktioniert, obwohl sie etwas hässlich ist. Es wird auch nicht in jeder Situation funktionieren, aber es funktioniert für mich. Da ich die Größe der Benutzeroberfläche an die Fenstergröße des iPad anpasse, kann der Benutzer normalerweise nicht scrollen. Mit anderen Worten, wenn ich das scrollTop des Fensters einstelle, bleibt es bei 0.

Wenn andererseits die Tastatur angezeigt wird, funktioniert das Scrollen plötzlich. So kann ich scrollTop einstellen, seinen Wert sofort testen und dann zurücksetzen. So könnte das mit jQuery im Code aussehen:

$(document).ready(function(){
    $('input').bind('focus',function() {
        $(window).scrollTop(10);
        var keyboard_shown = $(window).scrollTop() > 0;
        $(window).scrollTop(0);

        $('#test').append(keyboard_shown?'keyboard ':'nokeyboard ');
    });
});

Normalerweise würden Sie erwarten, dass dies für den Benutzer nicht sichtbar ist. Leider rollt das iPad zumindest beim Ausführen im Simulator sichtbar (wenn auch schnell) wieder auf und ab. Trotzdem funktioniert es zumindest in bestimmten Situationen.

Ich habe dies auf einem iPad getestet und es scheint gut zu funktionieren.

LKM
quelle
Ich habe ein Problem mit meiner Web-App, bei dem der Bildschirm ein wenig nach oben rollt, wenn die Eingabe fokussiert ist. Ich habe das Scrollen ansonsten deaktiviert, aber das Scrollen ist immer noch so. Irgendwelche Ideen? Vielen Dank [ stackoverflow.com/questions/6740253/…
Andrew Samuelsen
Ich habe das noch nicht ausprobiert, aber es sieht vielversprechend aus. Würde nicht .scrollTop(1)genauso gut funktionieren und weniger offensichtlich sein?
ThinkingStiff
1
Dies ist eine schlechte Idee ... Die Tastatur ist möglicherweise Bluetooth und die virtuelle Tastatur wird möglicherweise nicht angezeigt.
theSociableme
3
@theSociableme: Der springende Punkt dieser Lösung ist, die Bluetooth-Tastatur richtig zu handhaben. Wenn Sie Bluetooth-Tastaturen ignorieren, ist es einfach herauszufinden, ob die virtuelle Tastatur angezeigt wird, da Sie nur überprüfen können, ob ein Feld den Fokus hat.
LKM
5
@fraxture: Ich kenne keine umfassende Erklärung (wenn Sie eine recherchieren und schreiben, würde ich sie gerne lesen). Die beiden Plattformen behandeln Bildschirmtastaturen in ihren Hauptbrowsern sehr unterschiedlich. Android Chrome verkleinert die Höhe des Ansichtsfensters, um Platz für die Tastatur zu schaffen, sodass die Größe der Seite geändert wird, wenn die Tastatur angezeigt wird. iOS Safari überlagert die Seite mit der Tastatur (die Seitengröße bleibt gleich) und ändert die Funktionsweise des Bildlaufs. Safari scrollt beide Seiten im Ansichtsfenster und verschiebt gleichzeitig das Ansichtsfenster. Dabei wird sichergestellt, dass sich der untere Rand der Seite über der Tastatur befindet, wenn Sie ganz nach unten scrollen.
LKM
32

Sie können das Focusout- Ereignis verwenden, um eine Tastaturentlassung zu erkennen. Es ist wie Unschärfe, aber Blasen. Es wird ausgelöst, wenn die Tastatur geschlossen wird (aber natürlich auch in anderen Fällen). In Safari und Chrome kann das Ereignis nur mit addEventListener registriert werden, nicht mit älteren Methoden. Hier ist ein Beispiel, mit dem ich eine Phonegap-App nach dem Entlassen der Tastatur wiederhergestellt habe.

 document.addEventListener('focusout', function(e) {window.scrollTo(0, 0)});

Ohne dieses Snippet blieb der App-Container bis zur Seitenaktualisierung in der nach oben gescrollten Position.

Per Quested Aronsson
quelle
1
beste Lösung, die ich für mein Problem gefunden habe
Sutulustus
1
Sie können auch die 'Focusin'-Version verwenden, um das Öffnen der Tastatur zu erkennen.
A.Çetin
15

Vielleicht ist eine etwas bessere Lösung, das "Unschärfe" -Ereignis (in meinem Fall mit jQuery) an die verschiedenen Eingabefelder zu binden.

Dies liegt daran, dass beim Verschwinden der Tastatur alle Formularfelder unscharf werden. Für meine Situation löste dies das Problem.

$('input, textarea').bind('blur', function(e) {

       // Keyboard disappeared
       window.scrollTo(0, 1);

});

ich hoffe es hilft. Michele

Michele
quelle
Danke für diese Antwort. Ich fand es nützlich, ein Problem zu beheben, bei dem die iPad Safari-Tastatur dazu führte, dass der Textbereichscursor außerhalb des Textbereichs verschoben (versetzt) ​​wurde.
Kennbrodhagen
14

Wenn eine Bildschirmtastatur vorhanden ist, führt das Fokussieren eines Textfelds am unteren Rand des Ansichtsfensters dazu, dass Safari das Textfeld in die Ansicht scrollt. Es gibt möglicherweise eine Möglichkeit, dieses Phänomen auszunutzen, um das Vorhandensein der Tastatur zu erkennen (mit einem winzigen Textfeld am unteren Rand der Seite, das momentan den Fokus erhält, oder so ähnlich).

ianh
quelle
1
Das ist eine geniale Idee. Ich habe eine ähnliche Lösung gefunden, die auch die aktuelle Bildlaufposition verwendet, um die virtuelle Tastatur zu erkennen.
LKM
Genial! Du hast meinen Tag gerettet!
Aztack
11

Während des Fokusereignisses können Sie über die Dokumenthöhe und auf magische Weise über das Fenster scrollen. Die Höhe wird durch die Höhe der virtuellen Tastatur verringert. Beachten Sie, dass die Größe der virtuellen Tastatur für Quer- und Hochformat unterschiedlich ist. Sie müssen sie daher erneut erkennen, wenn sie sich ändert. Ich würde davon abraten, sich diese Werte zu merken, da der Benutzer jederzeit eine Bluetooth-Tastatur verbinden / trennen kann.

var element = document.getElementById("element"); // the input field
var focused = false;

var virtualKeyboardHeight = function () {
    var sx = document.body.scrollLeft, sy = document.body.scrollTop;
    var naturalHeight = window.innerHeight;
    window.scrollTo(sx, document.body.scrollHeight);
    var keyboardHeight = naturalHeight - window.innerHeight;
    window.scrollTo(sx, sy);
    return keyboardHeight;
};

element.onfocus = function () {
    focused = true;
    setTimeout(function() { 
        element.value = "keyboardHeight = " + virtualKeyboardHeight() 
    }, 1); // to allow for orientation scrolling
};

window.onresize = function () {
    if (focused) {
        element.value = "keyboardHeight = " + virtualKeyboardHeight();
    }
};

element.onblur = function () {
    focused = false;
};

Beachten Sie, dass bei Verwendung einer Bluetooth-Tastatur die Höhe der Tastatur 44 beträgt. Dies entspricht der Höhe der Symbolleiste [Zurück] [Weiter].

Es gibt ein kleines Flackern, wenn Sie diese Erkennung durchführen, aber es scheint nicht möglich zu sein, dies zu vermeiden.

Hafthor
quelle
5
Ich habe es gerade in iOS 8.2 versucht und es funktioniert nicht ... hat es irgendwann aufgehört, für neues iOS zu funktionieren?
Ming
1
Ich habe auch nicht für mich gearbeitet - Größenänderung wird in iOS9.3 nicht ausgelöst
llamerr
8

Bearbeiten: Von Apple dokumentiert, obwohl ich es nicht zum Laufen bringen konnte: WKWebView- Verhalten mit Tastaturanzeigen : "In iOS 10 entsprechen WKWebView-Objekte dem nativen Verhalten von Safari, indem sie ihre window.innerHeight-Eigenschaft aktualisieren, wenn die Tastatur angezeigt wird, und rufen nicht auf Ereignisse in der Größe ändern "(kann möglicherweise Fokus oder Fokus plus Verzögerung verwenden, um die Tastatur zu erkennen, anstatt die Größe zu ändern).

Bearbeiten: Code setzt Bildschirmtastatur voraus, keine externe Tastatur. Lassen Sie es, weil Informationen für andere nützlich sein können, die sich nur für Bildschirmtastaturen interessieren. Verwenden Sie http://jsbin.com/AbimiQup/4 , um Seitenparameter anzuzeigen.

Wir testen, ob document.activeElementes sich um ein Element handelt, das die Tastatur anzeigt (Eingabetyp = Text, Textbereich usw.).

Der folgende Code fummelt Dinge für unsere Zwecke (obwohl nicht allgemein korrekt).

function getViewport() {
    if (window.visualViewport && /Android/.test(navigator.userAgent)) {
        // https://developers.google.com/web/updates/2017/09/visual-viewport-api    Note on desktop Chrome the viewport subtracts scrollbar widths so is not same as window.innerWidth/innerHeight
        return {
            left: visualViewport.pageLeft,
            top: visualViewport.pageTop,
            width: visualViewport.width,
            height: visualViewport.height
        };
    }
    var viewport = {
            left: window.pageXOffset,   // http://www.quirksmode.org/mobile/tableViewport.html
            top: window.pageYOffset,
            width: window.innerWidth || documentElement.clientWidth,
            height: window.innerHeight || documentElement.clientHeight
    };
    if (/iPod|iPhone|iPad/.test(navigator.platform) && isInput(document.activeElement)) {       // iOS *lies* about viewport size when keyboard is visible. See http://stackoverflow.com/questions/2593139/ipad-web-app-detect-virtual-keyboard-using-javascript-in-safari Input focus/blur can indicate, also scrollTop: 
        return {
            left: viewport.left,
            top: viewport.top,
            width: viewport.width,
            height: viewport.height * (viewport.height > viewport.width ? 0.66 : 0.45)  // Fudge factor to allow for keyboard on iPad
        };
    }
    return viewport;
}


function isInput(el) {
    var tagName = el && el.tagName && el.tagName.toLowerCase();
    return (tagName == 'input' && el.type != 'button' && el.type != 'radio' && el.type != 'checkbox') || (tagName == 'textarea');
};

Der obige Code ist nur ungefähr: Er ist falsch für geteilte Tastatur, nicht angedockte Tastatur und physische Tastatur. Laut Kommentar oben können Sie möglicherweise einen besseren Job als den angegebenen Code auf Safari (seit iOS8?) Oder WKWebView (seit iOS10) mit machenwindow.innerHeight Eigenschaft .

Ich habe unter anderen Umständen Fehler festgestellt: z. B. den Fokus auf die Eingabe legen, dann zum Startbildschirm gehen und dann zur Seite zurückkehren; Das iPad sollte das Ansichtsfenster nicht verkleinern. alte IE-Browser funktionieren nicht, Opera hat nicht funktioniert, da Opera nach dem Schließen der Tastatur den Fokus auf das Element gelegt hat.

Die markierte Antwort (Ändern des Bildlauffelds zum Messen der Höhe) hat jedoch unangenehme Nebenwirkungen auf der Benutzeroberfläche, wenn das Ansichtsfenster zoombar ist (oder das Zoomen in den Einstellungen aktiviert ist). Ich verwende nicht die andere vorgeschlagene Lösung (Ändern des Bildlaufs), da unter iOS, wenn das Ansichtsfenster zoombar ist und zur fokussierten Eingabe gescrollt wird, fehlerhafte Interaktionen zwischen Scrollen & Zoomen & Fokussieren auftreten (die eine nur fokussierte Eingabe außerhalb des Ansichtsfensters belassen können - nicht sichtbar).

Robocat
quelle
Abhängig von den Browsern erkennt innerHeight Vollbildbrüche, wenn einige Elemente absolut positioniert sind. Überhaupt nicht verlässlich.
Udo
5

Nur auf Android 4.1.1 getestet:

Das Unschärfeereignis ist kein zuverlässiges Ereignis zum Testen der Tastatur nach oben und unten, da der Benutzer als Option zum expliziten Ausblenden der Tastatur ein Unschärfeereignis auf dem Feld auslöst, durch das die Tastatur angezeigt wurde.

Das Größenänderungsereignis funktioniert jedoch wie ein Zauber, wenn die Tastatur aus irgendeinem Grund nach oben oder unten geht.

Kaffee:

$(window).bind "resize", (event) ->  alert "resize"

Wird immer dann ausgelöst, wenn die Tastatur aus irgendeinem Grund angezeigt oder ausgeblendet wird.

Beachten Sie jedoch, dass es im Fall eines Android-Browsers (anstelle einer App) eine einziehbare URL-Leiste gibt, die beim Zurückziehen keine Größenänderung auslöst, jedoch die verfügbare Fenstergröße ändert.

user1650613
quelle
+1 für ein Unschärfeereignis, das beim manuellen Schließen der Tastatur nicht ausgelöst wird. Größenänderung ist eine gute Idee und würde für Android-Geräte gut funktionieren.
Ankit Garg
Kann bestätigen, dass dies sowohl auf einem iPhone 5 (iOS 6.0.2) als auch auf einem iPad 3 (iOS 6.0) funktioniert.
Diego Agulló
1
Gerade auf Chrome 41 unter iOS6 auf CrossBrowserTesting getestet - Die Größenänderung wird nicht durch das Erscheinen oder Verschwinden der virtuellen Tastatur ausgelöst.
Dan Dascalescu
4

Versuchen Sie, die Größe des Fensters zu ermitteln, anstatt die Tastatur zu erkennen

Wenn die Höhe des Fensters verringert wurde und die Breite immer noch gleich ist, bedeutet dies, dass die Tastatur eingeschaltet ist. Wenn die Tastatur nicht ausgeschaltet ist, können Sie auch hinzufügen, ob ein Eingabefeld scharfgestellt ist oder nicht.

Versuchen Sie diesen Code zum Beispiel.

var last_h = $(window).height(); //  store the intial height.
var last_w = $(window).width(); //  store the intial width.
var keyboard_is_on = false;
$(window).resize(function () {
    if ($("input").is(":focus")) {
        keyboard_is_on =
               ((last_w == $(window).width()) && (last_h > $(window).height()));
    }   
});     
KA
quelle
2
Das scheint in iOS 8 nicht mehr zu funktionieren. Die Tastatur überlagert den Inhalt und in vielen Fällen scrollt der Inhalt nach unten, wodurch anfänglich fokussierte Eingabefelder verdeckt werden.
Rick Strahl
3
Die Fensterhöhe gibt die Höhe einschließlich der Tastatur seit iOS 7 im IOS6-Fenster zurück. Die Höhe ändert sich, wenn die Tastatur geöffnet wird.
Michiel
1
Beachten Sie, dass sich die Höhe auch ändert, wenn die obere Adressleiste beim Scrollen in den Bildschirm hinein- und herausgeschoben wird. Sie sollten eine minimale Höhenänderung von 200 Pixel hinzufügen (nicht getestet).
Oriadam
1

Diese Lösung merkt sich die Bildlaufposition

    var currentscroll = 0;

    $('input').bind('focus',function() {
        currentscroll = $(window).scrollTop();
    });

    $('input').bind('blur',function() {
        if(currentscroll != $(window).scrollTop()){

        $(window).scrollTop(currentscroll);

        }
    });
WebsterDevelopine
quelle
1

Probier diese:

var lastfoucsin;

$('.txtclassname').click(function(e)
{
  lastfoucsin=$(this);

//the virtual keyboard appears automatically

//Do your stuff;

});


//to check ipad virtual keyboard appearance. 
//First check last focus class and close the virtual keyboard.In second click it closes the wrapper & lable

$(".wrapperclass").click(function(e)
{

if(lastfoucsin.hasClass('txtclassname'))
{

lastfoucsin=$(this);//to avoid error

return;

}

//Do your stuff 
$(this).css('display','none');
});`enter code here`
Nalini Amir
quelle
1

Wie in den vorherigen Antworten erwähnt, wird die Variable window.innerHeight jetzt unter iOS10 ordnungsgemäß aktualisiert, wenn die Tastatur angezeigt wird. Da ich die Unterstützung für frühere Versionen nicht benötige, habe ich den folgenden Hack entwickelt, der möglicherweise etwas einfacher ist als der diskutierte "Lösungen".

//keep track of the "expected" height
var windowExpectedSize = window.innerHeight;

//update expected height on orientation change
window.addEventListener('orientationchange', function(){
    //in case the virtual keyboard is open we close it first by removing focus from the input elements to get the proper "expected" size
    if (window.innerHeight != windowExpectedSize){
        $("input").blur();
        $("div[contentEditable]").blur();     //you might need to add more editables here or you can focus something else and blur it to be sure
        setTimeout(function(){
            windowExpectedSize = window.innerHeight;
        },100);
    }else{
        windowExpectedSize = window.innerHeight;
    }
});

//and update the "expected" height on screen resize - funny thing is that this is still not triggered on iOS when the keyboard appears
window.addEventListener('resize', function(){
    $("input").blur();  //as before you can add more blurs here or focus-blur something
    windowExpectedSize = window.innerHeight;
});

dann können Sie verwenden:

if (window.innerHeight != windowExpectedSize){ ... }

um zu überprüfen, ob die Tastatur sichtbar ist. Ich benutze es jetzt schon eine Weile in meiner Web-App und es funktioniert gut, aber (wie bei allen anderen Lösungen) kann es vorkommen, dass es fehlschlägt, weil die "erwartete" Größe nicht richtig aktualisiert wird oder so.

Fließen
quelle
Ich hatte gehofft, dass dies der Fall ist, aber nein, es wird nicht aktualisiert.
Sam Saffron
0

Ich habe etwas gesucht und konnte nichts Konkretes für ein "auf der Tastatur gezeigt" oder "auf der Tastatur entlassen" finden. Siehe die offizielle Liste der unterstützten Veranstaltungen . Siehe auch Technischer Hinweis TN2262 für iPad. Wie Sie wahrscheinlich bereits wissen, gibt es ein Körperereignis, das onorientationchangeSie verkabeln können, um Quer- / Hochformat zu erkennen.

Ähnlich, aber eine wilde Vermutung ... haben Sie versucht, die Größenänderung zu erkennen? Änderungen am Ansichtsfenster können dieses Ereignis indirekt über die angezeigte / ausgeblendete Tastatur auslösen.

window.addEventListener('resize', function() { alert(window.innerHeight); });

Was einfach die neue Höhe bei jedem Größenänderungsereignis alarmieren würde ...

slf
quelle
10
Leider hat die Tastatur in meinen Tests das Größenänderungsereignis nicht ausgelöst.
LKM
0

Ich habe es selbst nicht versucht, also ist es nur eine Idee ... aber haben Sie versucht, Medienabfragen mit CSS zu verwenden, um zu sehen, wann sich die Höhe des Fensters ändert, und dann das Design dafür zu ändern? Ich würde mir vorstellen, dass Safari Mobile die Tastatur nicht als Teil des Fensters erkennt, sodass dies hoffentlich funktionieren würde.

Beispiel:

@media all and (height: 200px){
    #content {height: 100px; overflow: hidden;}
}
Janae
quelle
2
Sehr kluge Idee. Leider hatte das Anzeigen der Tastatur in meinen Tests keinen Einfluss auf die Höhenwerte, die zum Auswerten von Medienabfragen verwendet wurden.
LKM
Ich kann bestätigen: Größe: 250px hat bei mir funktioniert (zumindest auf Android).
WoodrowShigeru
0

Das Problem ist, dass Geräte auch im Jahr 2014 Ereignisse zur Größenänderung des Bildschirms sowie Bildlaufereignisse uneinheitlich verarbeiten, während die Softtastatur geöffnet ist.

Ich habe festgestellt, dass insbesondere iOS einige seltsame Layoutfehler auslöst, selbst wenn Sie eine Bluetooth-Tastatur verwenden. Anstatt eine weiche Tastatur zu erkennen, musste ich nur auf Geräte zielen, die sehr schmal sind und über Touchscreens verfügen.

Ich verwende Medienabfragen (oder window.matchMedia ) zur Breitenerkennung und Modernizr zur Erkennung von Berührungsereignissen.

Pixelbandito
quelle
0

Vielleicht ist es einfacher, in den Einstellungen Ihrer App ein Kontrollkästchen zu aktivieren, mit dem der Benutzer die Option "Externe Tastatur angeschlossen" aktivieren kann.

Erklären Sie dem Benutzer im Kleingedruckten, dass externe Tastaturen in heutigen Browsern derzeit nicht erkennbar sind.

Ian White
quelle
1
Das Hinzufügen eines solchen Umschalters ist ein letzter Ausweg, der überhaupt nicht als akzeptabel angesehen werden sollte, es sei denn, es gibt keine andere Lösung, die die App nicht beschädigt. Dies sollte die Erstellung einer funktionierenden App nicht blockieren.
Adam Leggett
-2

Nun, Sie können erkennen, wann Ihre Eingabefelder den Fokus haben, und Sie kennen die Höhe der Tastatur. Es gibt auch CSS, um die Ausrichtung des Bildschirms zu erhalten, also denke ich, dass Sie es hacken können.

Sie möchten jedoch irgendwie mit dem Fall einer physischen Tastatur umgehen.

Stuntmouse
quelle