android google-chrome input scroll focus

Android no se desplaza correctamente en el foco de entrada si no en el elemento del cuerpo



overscroll behavior y (4)

Este es un error en el navegador nativo de Android. Por cierto, la entrada se desplaza a la vista después de escribir un carácter en el teclado virtual.

El siguiente fragmento de código colocado en algún lugar de la página debería ayudar:

if(/Android 4/.[0-3]/.test(navigator.appVersion)){ window.addEventListener("resize", function(){ if(document.activeElement.tagName=="INPUT"){ window.setTimeout(function(){ document.activeElement.scrollIntoViewIfNeeded(); },0); } }) }

Cuando un navegador móvil muestra un teclado, intenta mover las barras de desplazamiento para que la entrada aún esté visible.

En iOS Safari, parece hacer esto correctamente al encontrar el padre desplazable más cercano .

En el navegador Android nativo de Android o Chrome, parece que solo prueba el elemento del cuerpo y luego se da por vencido, por lo que la entrada enfocada se oculta debajo del teclado.

Cómo romperlo

Establecer overflow-y: hidden en el elemento del cuerpo. Crea un contenedor desplazable y pon un formulario allí.

Cuando selecciona un elemento cerca de la parte inferior de su pantalla, el teclado lo oscurecerá.

Manifestación

http://dominictobias.com/android-scroll-bug/

<!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"/> <title>Android scroll/focus bug</title> <style> html, body { margin: 0; padding: 0; height: 100%; overflow: hidden; } .scroll { position: absolute; top: 0; right: 0; bottom: 0; left: 0; overflow-y: scroll; } input { margin-bottom: 20px; width: 100%; } </style> </head> <body> <div class="scroll"> <input type="text" value="Input 1"> <input type="text" value="Input 2"> <input type="text" value="Input 3"> <input type="text" value="Input 4"> <input type="text" value="Input 5"> <input type="text" value="Input 6"> <input type="text" value="Input 7"> <input type="text" value="Input 8"> <input type="text" value="Input 9"> <input type="text" value="Input 10"> <input type="text" value="Input 11"> <input type="text" value="Input 12"> <input type="text" value="Input 13"> <input type="text" value="Input 14"> <input type="text" value="Input 15"> <input type="text" value="Input 16"> <input type="text" value="Input 17"> <input type="text" value="Input 18"> <input type="text" value="Input 19"> <input type="text" value="Input 20"> </div> </body> </html>

Alguna idea de cómo solucionar este problema? ¿Se requiere alguna detección de navegador y hacks desordenados?


La respuesta de Serge es genial, pero tuve algunas modificaciones que mejoraron para mí.

El problema apareció en Android 6 también para mí, así que lo agregué al cheque y necesitaba la solución para trabajar tanto en las áreas de texto como en las entradas.

if(/Android [4-6]/.test(navigator.appVersion)) { window.addEventListener("resize", function() { if(document.activeElement.tagName=="INPUT" || document.activeElement.tagName=="TEXTAREA") { window.setTimeout(function() { document.activeElement.scrollIntoViewIfNeeded(); },0); } }) }

Si alguien necesita la solución en Angular 1, aquí está lo que utilicé allí.

angular.module(''<module name>'').run(function ($window, $timeout) { if(/Android [4-6]/.test($window.navigator.appVersion)){ $window.addEventListener("resize", function(){ if(document.activeElement.tagName=="INPUT" || document.activeElement.tagName=="TEXTAREA"){ $timeout(function() { document.activeElement.scrollIntoViewIfNeeded(); }); } }); } });


Ofreciendo una ligera revisión si le ahorra a alguien algo de tiempo:

  • No es necesario especificar una versión de Android # (es menos probable que se rompa cuando tu usuario obtenga Android 7.0+)
  • No es necesario envolver en un setTimeOut
  • MDN informa contra .scrollIntoViewIfNeeded bc de la incompatibilidad del navegador => .scrollIntoView es un sustituto viable con un poco más de compatibilidad con el navegador

    if(/Android/.test(navigator.appVersion)) { window.addEventListener("resize", function() { if(document.activeElement.tagName=="INPUT" || document.activeElement.tagName=="TEXTAREA") { document.activeElement.scrollIntoView(); } }) }


Mirando esto de manera ligeramente diferente, el error parece ser causado por la función Sugerencias del navegador. Como realmente no quiero las sugerencias de todos modos, he usado:

if(/Android/.test(navigator.appVersion)){ $(''input[type="text"]'').attr(''autocomplete'', "off"); }

que da una experiencia mucho más suave.