it-swarm.com.de

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

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 an den verbleibenden Platz anzupassen, wenn die Tastatur angezeigt wird. Ich habe jedoch keine Möglichkeit gefunden zu erkennen, 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 die Bildhöhe von DOM-Elementen, und ich habe keine proprietären Ereignisse oder Eigenschaften gefunden, die angeben, ob die Tastatur sichtbar ist.

137
LKM

Ich habe eine Lösung gefunden, die funktioniert, obwohl sie etwas hässlich ist. Es funktioniert auch nicht in jeder Situation, 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 auf 0.

Wenn dagegen die Tastatur angezeigt wird, funktioniert das Scrollen plötzlich. So kann ich scrollTop einstellen, sofort seinen Wert testen und ihn dann zurücksetzen. So sieht das im Code aus, wenn Sie jQuery verwenden:

$(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 läuft das iPad, zumindest im Simulator, sichtbar (wenn auch schnell) auf und ab. Trotzdem funktioniert es zumindest in bestimmten Situationen.

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

53
LKM

Sie können das Ereignis focusout verwenden, um die Entlassung der Tastatur zu erkennen. Es ist wie Unschärfe, aber Blasen. Es wird ausgelöst, wenn die Tastatur geschlossen wird (natürlich auch in anderen Fällen). In Safari und Chrome kann das Ereignis nur bei addEventListener registriert werden, nicht bei älteren Methoden. Hier ist ein Beispiel, das ich zum Wiederherstellen einer Phonegap-App nach der Tastaturkündigung verwendet habe. 

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

Ohne dieses Snippet blieb der App-Container bis zur Seitenaktualisierung in der aufgerollten Position.

28

eine etwas bessere Lösung ist vielleicht (bei jQuery in meinem Fall) das "Unschärfe" -Ereignis an den verschiedenen Eingabefeldern zu binden.

Dies liegt daran, dass alle Formularfelder verschwommen sind, wenn die Tastatur nicht mehr angezeigt wird .. Für diese Situation wurde das Problem dadurch gelöst.

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

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

});

ich hoffe es hilft .... Michele

15
Michele

Wenn eine Bildschirmtastatur vorhanden ist, wird das Textfeld durch das Fokussieren eines Textfelds am unteren Rand des Ansichtsfensters in Sicht gebracht. Es gibt eine Möglichkeit, dieses Phänomen zu nutzen, um das Vorhandensein der Tastatur zu erkennen (mit einem winzigen Textfeld am unteren Rand der Seite, das augenblicklich den Fokus erhält, oder so ähnlich).

14
ianh

Während des Fokus-Ereignisses können Sie an der Dokumenthöhe vorbeiziehen und das Fenster auf magische Weise durchblättern. Beachten Sie, dass die Größe der virtuellen Tastatur sich bei Querformat-Ausrichtung im Hochformat unterscheidet. Sie müssen sie daher erneut erkennen, wenn sie sich ändert. Ich würde davon abraten, sich an diese Werte zu erinnern, da der Benutzer jederzeit eine Bluetooth-Tastatur anschließen oder trennen könnte.

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;
};

Wenn der Benutzer eine Bluetooth-Tastatur verwendet, ist keyboardHeight 44, was der Höhe der Symbolleiste [Vorherige] [Nächste] entspricht.

Wenn Sie diese Erkennung durchführen, gibt es ein kleines Flimmern, aber es scheint nicht möglich, dies zu vermeiden.

11
Hafthor

Edit: Von Apple dokumentiert, obwohl ich es nicht wirklich zum Laufen bringen konnte: WKWebView Verhalten mit Tastaturanzeigen : "In iOS 10 passen WKWebView-Objekte das native Verhalten von Safari, indem sie ihre window.innerHeight-Eigenschaft aktualisieren, wenn die Tastatur angezeigt wird. und rufen Sie keine Größenänderungsereignisse auf "(möglicherweise können Fokus oder Fokus plus Verzögerung zum Erkennen der Tastatur anstelle der Größenänderung verwendet werden).

Bearbeiten: Der Code setzt eine Bildschirmtastatur voraus, keine externe Tastatur. Wenn Sie diese Option verlassen, kann die Info für andere Benutzer von Interesse sein, die sich nur für Bildschirm-Tastaturen interessieren. Verwenden Sie http://jsbin.com/AbimiQup/4 , um Seitenparameter anzuzeigen.

Wir testen, ob das document.activeElement ein Element ist, das die Tastatur anzeigt (Eingabetyp = Text, Textbereich usw.).

Der folgende Code fälscht Dinge für unsere Zwecke (obwohl nicht generell 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 ein Näherungswert: Er ist falsch für geteilte Tastatur, gedockte Tastatur und physische Tastatur. Wie im obigen Kommentar oben beschrieben, können Sie unter Umständen die Arbeit mit Safari (seit iOS8?) Oder WKWebView (seit iOS10) mit der window.innerHeight-Eigenschaft verbessern. 

Ich habe Fehler unter anderen Umständen gefunden: z. Geben Sie den Fokus auf die Eingabe, gehen Sie zum Startbildschirm und kehren Sie dann zur Seite zurück. iPad sollte Viewport nicht kleiner machen; alte IE - Browser funktionieren nicht, Opera funktionierte nicht, da Opera den Fokus auf das Element nach dem Schließen der Tastatur beibehielt.

Die getaggte Antwort (Ändern des Bildlaufs zum Messen der Höhe) hat jedoch unangenehme Nebeneffekte der Benutzeroberfläche, wenn der Ansichtsbereich zoombar ist (oder in den Voreinstellungen Force-Zoom aktiviert ist). Ich verwende die andere vorgeschlagene Lösung nicht (Ändern des Bildlaufs), da unter iOS beim Zoomen von Zoomfenstern und dem Fokussieren auf fokussierte Eingaben fehlerhafte Interaktionen zwischen Bildlauf und Zoom & Fokus (das kann eine fokussierte Eingabe außerhalb des Ansichtsfensters hinterlassen) - nicht sichtbar).

8
robocat

Nur auf Android 4.1.1 getestet:

unschärfeereignis ist kein zuverlässiges Ereignis zum Testen der Tastatur nach oben und unten, da der Benutzer die Tastatur explizit ausblenden kann, wodurch kein Unschärfereignis für das Feld ausgelöst wird, das die Anzeige der Tastatur verursacht hat.

die Größenänderung von Ereignissen funktioniert jedoch wie ein Zauber, wenn die Tastatur aus irgendeinem Grund hoch- oder heruntergefahren wird.

kaffee: 

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

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

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

5
user1650613

Versuchen Sie statt der Tastatur die Größe des Fensters zu ermitteln

Wenn die Höhe des Fensters reduziert wurde und die Breite immer noch gleich ist, bedeutet dies, dass die Tastatur eingeschaltet ist. Andernfalls ist die Tastatur deaktiviert. Sie können auch hinzufügen, ob ein Eingabefeld im Fokus 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()));
    }   
});     
3
K.A

Wie bereits in den vorherigen Antworten erwähnt, wird die Variable window.innerHeight jetzt auf iOS10 ordnungsgemäß aktualisiert wenn die Tastatur angezeigt wird und da ich keine Unterstützung für frühere Versionen brauche, kam ich mit dem folgenden Hack, der vielleicht etwas ist einfacher als die diskutierten "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 kannst du verwenden:

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

um zu überprüfen, ob die Tastatur sichtbar ist. Ich verwende es bereits seit einiger Zeit 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 ordnungsgemäß aktualisiert wird oder so.

1
Flow

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`
1
Nalini Amir

Diese Lösung speichert die Bildlaufposition 

    var currentscroll = 0;

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

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

        $(window).scrollTop(currentscroll);

        }
    });
1

Wenn im Safari-Browser ein Element am unteren Rand des Bildschirms positioniert ist und die virtuelle Tastatur sichtbar ist, erhöht sich diese Position um etwa 1 Pixel. Sie können das ausnutzen.

Angenommen, es ist ein mobiles Gerät im Querformat

<div id="detector" style="position: absolute; bottom: 0"></div>

const detector = document.querySelector('#detector');
detector.getBoundingClientRect().bottom // 320

// when virtual keyboard is visible
detector.getBoundingClientRect().bottom // 329 or 328
0
Udo

Vielleicht ist es einfacher, ein Kontrollkästchen in den Einstellungen Ihrer App zu haben, in dem der Benutzer die externe Tastatur anwählen kann.

Erklären Sie dem Benutzer im Kleingedruckten, dass externe Tastaturen in heutigen Browsern derzeit nicht erkannt werden können.

0
Ian White

Ich habe es nicht selbst 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 könnte mir vorstellen, dass Safari Mobile die Tastatur nicht als Teil des Fensters erkennt, was hoffentlich funktionieren würde.

Beispiel:

@media all and (height: 200px){
    #content {height: 100px; overflow: hidden;}
}
0
Janae

Das Problem ist, dass die Geräte auch 2014 die Bildschirmgrößenänderung sowie Bildlaufereignisse inkonsistent behandeln, während die Soft-Tastatur geöffnet ist.

Ich habe festgestellt, dass auch bei Verwendung einer Bluetooth-Tastatur insbesondere iOS einige merkwürdige Layout-Fehler auslöst. Anstatt eine Soft-Tastatur zu erkennen, musste ich nur Geräte ansprechen, die sehr schmal sind und Touchscreens aufweisen.

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

0
pixelbandito

Ich suchte ein wenig und fand nichts Konkretes für ein "auf der Tastatur angezeigtes" oder "auf der Tastatur abgelehntes". Siehe die offizielle Liste der unterstützten Ereignisse . Siehe auch Technical Note TN2262 für iPad. Wie Sie wahrscheinlich bereits wissen, gibt es ein Körperereignis onorientationchange, das Sie verbinden können, um Querformat/Porträt zu erkennen.

Ähnlich, aber eine wilde Vermutung ... haben Sie versucht, die Größenänderung zu ermitteln? Viewport-Änderungen können dieses Ereignis indirekt auslösen, indem die Tastatur ein-/ausgeblendet wird.

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

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

0
slf