Aplicación web iPad: ¿Detecta el teclado virtual usando JavaScript en Safari?


Answers

Puede usar el evento de enfoque para detectar el despido del teclado. Es como borroso, pero burbujas. Se disparará cuando el teclado se cierre (pero también en otros casos, por supuesto). En Safari y Chrome, el evento solo se puede registrar con addEventListener, no con métodos heredados. Aquí hay un ejemplo que utilicé para restaurar una aplicación Phonegap después del despido del teclado.

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

Sin este fragmento, el contenedor de la aplicación se mantuvo en la posición desplazada hasta la actualización de la página.

Question

Estoy escribiendo una aplicación web para el iPad ( no es una aplicación de la tienda de aplicaciones habitual, está escrita con HTML, CSS y JavaScript). Dado que el teclado ocupa una gran parte de la pantalla, tendría sentido cambiar el diseño de la aplicación para que se ajuste al espacio restante cuando se muestra el teclado. Sin embargo, no he encontrado manera de detectar cuándo o si se muestra el teclado.

Mi primera idea fue suponer que el teclado está visible cuando un campo de texto tiene foco. Sin embargo, cuando se conecta un teclado externo a un iPad, el teclado virtual no aparece cuando un campo de texto recibe el foco.

En mis experimentos, el teclado tampoco afectó la altura o altura de desplazamiento de ninguno de los elementos DOM, y no he encontrado eventos o propiedades que indiquen si el teclado está visible.




Prueba este:

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`



Bueno, puedes detectar cuándo tus cuadros de entrada tienen el foco, y sabes la altura del teclado. También hay CSS disponible para obtener la orientación de la pantalla, así que creo que puedes hackearla.

Sin embargo, querría manejar el caso de un teclado físico de alguna manera.




Como se señaló en las respuestas anteriores en algún lugar, la variable window.innerHeight se actualiza correctamente ahora en iOS10 cuando aparece el teclado y como no necesito el soporte para versiones anteriores, se me ocurrió el siguiente truco que podría ser un poco más fácil que el discutido "soluciones".

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

entonces puedes usar:

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

para verificar si el teclado está visible. Lo he estado utilizando durante un tiempo en mi aplicación web y funciona bien, pero (como todas las demás soluciones) es posible que encuentre una situación en la que falla porque el tamaño "esperado" no se actualiza correctamente o algo así.




No lo he intentado solo, así que es solo una idea ... pero ¿has intentado utilizar las consultas de medios con CSS para ver cuándo cambia el alto de la ventana y luego cambiar el diseño para eso? Me imagino que el móvil de Safari no reconoce el teclado como parte de la ventana, así que con suerte funcionaría.

Ejemplo:

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



Editar: Documentado por Apple, aunque no pude hacerlo funcionar: WKWebView Behavior with Keyboard Displays : "En iOS 10, los objetos WKWebView coinciden con el comportamiento nativo de Safari actualizando su propiedad window.innerHeight cuando se muestra el teclado, y no llaman cambiar el tamaño de los eventos "(quizás se puede usar el enfoque o el enfoque más la demora para detectar el teclado en lugar de usar el tamaño).

Editar: el código presume el teclado en pantalla, no el teclado externo. Dejarlo porque la información puede ser útil para otros que solo se preocupan por los teclados en pantalla. Use http://jsbin.com/AbimiQup/4 para ver los parámetros de la página.

Probamos para ver si document.activeElement es un elemento que muestra el teclado (tipo de entrada = texto, área de texto, etc.).

El siguiente código modifica las cosas para nuestros propósitos (aunque generalmente no es correcto).

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://.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');
};

El código anterior es solo aproximado: es incorrecto para teclado dividido, teclado desacoplado, teclado físico. Como se comenta en la parte superior, es posible que puedas hacer un mejor trabajo que el código dado en Safari (desde iOS8?) O WKWebView (desde iOS10) usando la propiedad window.innerHeight .

He encontrado fallas en otras circunstancias: por ejemplo, dar enfoque a la entrada, luego ir a la pantalla de inicio y luego volver a la página; iPad no debería hacer que la ventana gráfica sea más pequeña; los viejos navegadores IE no funcionarán, Opera no funcionó porque Opera mantuvo el foco en el elemento después de que el teclado se cerró.

Sin embargo, la respuesta etiquetada (cambio de desplazamiento para medir la altura) tiene efectos secundarios desagradables en la interfaz de usuario si la vista se puede ampliar (o se puede activar el zoom en las preferencias). No utilizo la otra solución sugerida (cambio scrolltop) porque en iOS, cuando la ventana gráfica es ampliable y se desplaza a la entrada enfocada, hay interacciones erróneas entre desplazamiento y zoom & focus (que pueden dejar una entrada enfocada solo fuera de la ventana gráfica, no visible).




Si hay un teclado en pantalla, al enfocar un campo de texto que está cerca de la parte inferior de la ventana gráfica, Safari desplazará el campo de texto a la vista. Puede haber alguna forma de explotar este fenómeno para detectar la presencia del teclado (tener un pequeño campo de texto en la parte inferior de la página que gana foco momentáneamente, o algo así).




En lugar de detectar el teclado, intente detectar el tamaño de la ventana

Si se redujo la altura de la ventana y el ancho sigue siendo el mismo, significa que el teclado está encendido. De lo contrario, el teclado está apagado, también puede agregar a eso, probar si algún campo de entrada está enfocado o no.

Pruebe este código, por ejemplo.

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





Related