iOS 5 posicionamiento fijo y teclado virtual

138

Tengo un sitio web móvil que tiene un div anclado en la parte inferior de la pantalla a través de la posición: fijo. Todo funciona bien en iOS 5 (estoy probando en un iPod Touch) hasta que esté en una página con un formulario. Cuando toco un campo de entrada y aparece el teclado virtual, de repente se pierde la posición fija de mi div. El div ahora se desplaza con la página siempre que el teclado esté visible. Una vez que hago clic en Listo para cerrar el teclado, el div vuelve a su posición en la parte inferior de la pantalla y obedece a la posición: regla fija.

¿Alguien más ha experimentado este tipo de comportamiento? ¿Se espera esto? Gracias.

jeffc
fuente
Sí, parece que Apple no lo pensó tan bien para IOS5. Cualquier elemento de posición fija se vuelve relativo a la página tan pronto como aparece el teclado virtual. Probablemente estaría bien si los elementos volvieran a una posición absoluta, ya que esto no rompería el diseño. Lamentablemente, la ubicación real de estos elementos es mucho menos predecible. Tengo este problema exacto con mi encabezado fijo en [ELIMINADO]. Desplácese hacia abajo en la página, luego haga clic en el cuadro de búsqueda y explote ... diseño roto. Incluso he tratado de solucionarlo volviendo al posicionamiento absoluto en el evento de enfoque, que funciona, pero luego pierdo
John williams
2
Me he encontrado con este mismo problema. ¿Alguien ha presentado un error con Apple para ver cómo solucionarlo? Además, ¿alguien más ha visto este comportamiento continuar en iOS6?
Robert Hui
1
Me encuentro con el mismo problema con iOS6.
Redtopia
24
¡El mismo problema todavía parece existir en iOS7!
Ria Weyprecht
55
No parece estar solucionado en iOS 8 ...
contactmatt

Respuestas:

49

Tuve este problema en mi solicitud. Así es como estoy trabajando para solucionarlo:

input.on('focus', function(){
    header.css({position:'absolute'});
});
input.on('blur', function(){
    header.css({position:'fixed'});
});

Solo estoy desplazándome hacia la parte superior y posicionándolo allí, para que el usuario de iOS no note nada extraño. Envuelva esto en alguna detección de agente de usuario para que otros usuarios no obtengan este comportamiento.

Nick Retallack
fuente
Literalmente tropecé con este problema hoy y este parecía el más razonable, +1.
Daniel
3
Esto funciona bastante bien. Solo llamo a esto para dispositivos iOS: var isIOS = /(iPad|iPhone|iPod)/g.test(navigator.userAgent);
Redtopia
8
También eliminé $ (window) .scrollTop (0) ... No creo que sea necesario y causó desplazamiento no deseado.
Redtopia
1
O simplemente document.body.scrollTop = 0si no está utilizando jQuery y apunta a los últimos navegadores.
Langdon
En formularios más largos, la configuración $(window).scrollTop(0);puede hacer que la entrada enfocada se mueva fuera de la pantalla, por ejemplo, una entrada más abajo en la página, o si un iPhone está en vertical. Una mejor solución es el conjunto de enfoque header.css({position:'absolute',top:window.pageYOffset+'px'});y el conjunto de desenfoque header.css({position:'fixed',top:0});.
robocat el
16

Tuve un problema de ipad ligeramente diferente en el que el teclado virtual empujó mi ventana gráfica fuera de la pantalla. Luego, después de que el usuario cerró el teclado virtual, mi ventana gráfica todavía estaba fuera de la pantalla. En mi caso hice algo como lo siguiente:

var el = document.getElementById('someInputElement');
function blurInput() {
    window.scrollTo(0, 0);
}
el.addEventListener('blur', blurInput, false);
ds111
fuente
3
No me ayuda :(
Dmitry
@Altaveron. Lamento escuchar eso. Fue por un problema específico que estaba teniendo en ios6 y dispositivos inferiores. No he vuelto a visitar desde entonces.
ds111
14

Este es el código que usamos para solucionar el problema con ipad. Básicamente, detecta discrepancias entre la posición de desplazamiento y desplazamiento, lo que significa que 'fijo' no funciona correctamente.

$(window).bind('scroll', function () {
    var $nav = $(".navbar")
    var scrollTop = $(window).scrollTop();
    var offsetTop = $nav.offset().top;

    if (Math.abs(scrollTop - offsetTop) > 1) {
        $nav.css('position', 'absolute');
        setTimeout(function(){
            $nav.css('position', 'fixed');
        }, 1);
    }
});
Escotilla
fuente
Es del complemento jquery.timers. Puede usar window.setTimeout en su lugar.
Hatch
activar esta misma función en el desenfoque de entrada y el enfoque también ayudará
Blowsie
Genio, realmente cava esto. También +1 a la sugerencia de @ Blowsie de usar esto de enfoque y desenfoque en lugar de desplazamiento.
Skone
12

Los elementos de posición fija simplemente no actualizan su posición cuando el teclado está arriba. Sin embargo, descubrí que engañando a Safari para que pensara que la página ha cambiado de tamaño, los elementos se reubicarán. No es perfecto, pero al menos no tiene que preocuparse por cambiar a 'posición: absoluta' y seguir los cambios usted mismo.

El siguiente código solo escucha cuándo es probable que el usuario esté usando el teclado (debido a que una entrada está enfocada), y hasta que escuche un desenfoque, solo escucha cualquier evento de desplazamiento y luego realiza el truco de cambio de tamaño. Parece estar funcionando bastante bien para mí hasta ahora.

    var needsScrollUpdate = false;
    $(document).scroll(function(){
        if(needsScrollUpdate) {
            setTimeout(function() {
                $("body").css("height", "+=1").css("height", "-=1");
            }, 0);
        }
    });
    $("input, textarea").live("focus", function(e) {
        needsScrollUpdate = true;
    });

    $("input, textarea").live("blur", function(e) {
        needsScrollUpdate = false;
    });
Riley Dutton
fuente
En realidad, esto no funcionó para mí en el iPad. Terminé cambiando la posición del pie de página fijo a relativo y tengo el pie de página en la parte inferior de la página hasta que se detectó el evento de desenfoque de entrada cuando cambié la posición a fijo.
Akrikos
66
Ya no funciona, iOS probablemente solucionó cualquier error que hiciera que esto funcionara
Kevin
6

En caso de que alguien se encuentre con este hilo como lo hice mientras investigaba este problema. Encontré este hilo útil para estimular mi pensamiento sobre este tema.

Esta fue mi solución para esto en un proyecto reciente. Solo necesita cambiar el valor de "targetElem" a un selector jQuery que represente su encabezado.

if(navigator.userAgent.match(/iPad/i) != null){

var iOSKeyboardFix = {
      targetElem: $('#fooSelector'),
      init: (function(){
        $("input, textarea").on("focus", function() {
          iOSKeyboardFix.bind();
        });
      })(),

      bind: function(){
            $(document).on('scroll', iOSKeyboardFix.react);  
                 iOSKeyboardFix.react();      
      },

      react: function(){

              var offsetX  = iOSKeyboardFix.targetElem.offset().top;
              var scrollX = $(window).scrollTop();
              var changeX = offsetX - scrollX; 

              iOSKeyboardFix.targetElem.css({'position': 'fixed', 'top' : '-'+changeX+'px'});

              $('input, textarea').on('blur', iOSKeyboardFix.undo);

              $(document).on('touchstart', iOSKeyboardFix.undo);
      },

      undo: function(){

          iOSKeyboardFix.targetElem.removeAttr('style');
          document.activeElement.blur();
          $(document).off('scroll',iOSKeyboardFix.react);
          $(document).off('touchstart', iOSKeyboardFix.undo);
          $('input, textarea').off('blur', iOSKeyboardFix.undo);
      }
};

};

Hay una pequeña demora en la reparación porque iOS detiene la manipulación del DOM mientras se desplaza, pero hace el truco ...

Jory Cunningham
fuente
Esto funciona muy bien hasta iOS 7. ¿Alguien más tiene problemas con el elemento colocado correctamente pero desapareciendo?
Rona Kilmer
@RonaKilmer Cambia la función inita una función regular (no se invoca automáticamente; se dispara demasiado pronto). Luego llame iOSKeyboardFix.init();justo antes del final de la ifdeclaración.
cfree
@cfree Gracias, lo implementé hace un tiempo pero ese no es mi problema. Algo más está sucediendo. Uno de mis elementos fijos desaparece cuando se reposiciona. El otro no. No puedo culpar eso a la corrección del teclado ya que no está sucediendo en todas partes. No he visto que nadie más tenga el mismo problema, así que tendré que profundizar más.
Rona Kilmer
4

Ninguna de las otras respuestas que he encontrado para este error me ha funcionado. Pude solucionarlo simplemente desplazando la página hacia arriba en 34px, la cantidad de safari móvil la desplaza hacia abajo. con jquery:

$('.search-form').on('focusin', function(){
    $(window).scrollTop($(window).scrollTop() + 34);
});

Obviamente, esto tendrá efecto en todos los navegadores, pero evita que se rompa en iOS.

NealJMD
fuente
4

Este problema es realmente molesto.

Combiné algunas de las técnicas mencionadas anteriormente y se me ocurrió esto:

$(document).on('focus', 'input, textarea', function() {
    $('.YOUR-FIXED-DIV').css('position', 'static');
});

$(document).on('blur', 'input, textarea', function() {
    setTimeout(function() {
        $('.YOUR-FIXED-DIV').css('position', 'fixed');
        $('body').css('height', '+=1').css('height', '-=1');
    }, 100);
});

Tengo dos barras de navegación fijas (encabezado y pie de página, usando twitter bootstrap). Ambos actuaron de manera extraña cuando el teclado está arriba y extraño otra vez después de que el teclado está abajo.

Con esta solución cronometrada / retrasada funciona. Todavía encuentro un problema técnico de vez en cuando, pero parece ser lo suficientemente bueno como para mostrárselo al cliente.

Hazme saber si esto funciona para ti. Si no, podemos encontrar algo más. Gracias.

escapado
fuente
2
No parece necesitar ese tiempo de espera (al menos funcionaba bien para mí sin él), y si también sucede en elementos seleccionados, aparte de eso, esta solución funciona muy bien.
Phillip Gooch
3

Estaba experimentando el mismo problema con iOS7. Los elementos fijos inferiores estropearían mi vista al no enfocar correctamente.

Todo comenzó a funcionar cuando agregué esta metaetiqueta a mi html.

<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no,height=device-height" >

La parte que marcó la diferencia fue:

height=device-height

Espero que ayude a alguien.

pasevin
fuente
Gracias @pasevin. Esto solucionó mi problema en iOS 9.3.2
stillatmylinux
3

Me he tomado Jory Cunningham respuesta y la mejoré:

En muchos casos, no es solo un elemento el que se vuelve loco, sino varios elementos de posición fija, por lo que en este caso, targetElem debería ser un objeto jQuery que tenga todos los elementos fijos que desea "arreglar". Ho, esto parece hacer que el teclado iOS desaparezca si te desplazas ...

No hace falta mencionar que debe usar este evento de documento DESPUÉSDOM ready o justo antes de la </body>etiqueta de cierre .

(function(){
    var targetElem = $('.fixedElement'), // or more than one
        $doc       = $(document),
        offsetY, scrollY, changeY;

    if( !targetElem.length || !navigator.userAgent.match(/iPhone|iPad|iPod/i) )
        return;

    $doc.on('focus.iOSKeyboardFix', 'input, textarea, [contenteditable]', bind);

    function bind(){
        $(window).on('scroll.iOSKeyboardFix', react);
        react();
    }

    function react(){
        offsetY = targetElem.offset().top;
        scrollY = $(window).scrollTop();
        changeY = offsetY - scrollY;

        targetElem.css({'top':'-'+ changeY +'px'});

        // Instead of the above, I personally just do:
        // targetElem.css('opacity', 0);

        $doc.on('blur.iOSKeyboardFix', 'input, textarea, [contenteditable]', unbind)
            .on('touchend.iOSKeyboardFix', unbind);
    }

    function unbind(){
        targetElem.removeAttr('style');
        document.activeElement.blur();

        $(window).off('scroll.iOSKeyboardFix');
        $doc.off('touchend.iOSKeyboardFix blur.iOSKeyboardFix');
    }
})();
vsync
fuente
2
@vsync disculpas, no tenía idea de que eras un 'maestro de cocina'
Mike
cuando se selecciona, el foco de entrada en ese encabezado de tiempo se mueve hacia arriba (no visible) .Quiero fijar el div de encabezado al enfocar la selección y los archivos de entrada. alguien por favor ayúdame
VK Chikkadamalla
2

Tengo una solución similar a @NealJMD, excepto que la mía solo se ejecuta para iOS y determina correctamente el desplazamiento del desplazamiento midiendo el scollTop antes y después del desplazamiento del teclado nativo, así como usando setTimeout para permitir que ocurra el desplazamiento nativo:

var $window = $(window);
var initialScroll = $window.scrollTop();
if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {
  setTimeout(function () {
    $window.scrollTop($window.scrollTop() + (initialScroll - $window.scrollTop()));
  }, 0);
}
ChrisWren
fuente
1

He arreglado la posición fija de mi diseño principal de Ipad de esta manera:

var mainHeight;
var main = $('.main');

// hack to detects the virtual keyboard close action and fix the layout bug of fixed elements not being re-flowed
function mainHeightChanged() {
    $('body').scrollTop(0);
}

window.setInterval(function () {
    if (mainHeight !== main.height())mainHeightChanged();
    mainHeight = main.height();
}, 100);
Brett
fuente
Esto funcionó muy bien para mí en una complicada combinación de JQUery UI Dialog y On-Screen Keyboard que dejó mi diseño en la mitad de la pantalla cuando el diálogo y el teclado están cerrados al mismo tiempo, aunque con un par de ediciones: var main = $ (' body div '). first (); ... y ... función mainHeightChanged () {$ (top) .scrollTop (0); }
Awerealis
1
setInterval... ¿De Verdad? es mejor sólo para estancia con el error de hacer esto
VSYNC
1

Tuve un problema similar a @ ds111 s. Mi sitio web fue empujado hacia arriba por el teclado pero no se movió hacia abajo cuando el teclado se cerró.

Primero probé la solución @ ds111 pero tenía dos inputcampos. Por supuesto, primero el teclado desaparece, luego ocurre el desenfoque (o algo así). Entonces el segundoinput estaba debajo del teclado, cuando el foco cambiaba directamente de una entrada a la otra.

Además, el "salto hacia arriba" no fue lo suficientemente bueno para mí, ya que toda la página solo tiene el tamaño del ipad. Así que hice el desplazamiento suave.

Finalmente, tuve que adjuntar el detector de eventos a todas las entradas, incluso aquellas que estaban ocultas actualmente, de ahí el live.

Todos juntos puedo explicar el siguiente fragmento de javascript como: Adjunte el siguiente detector de eventos borrosos al actual y todo el futuro inputy textarea(= live): Espere un período de gracia (= window.setTimeout(..., 10)) y desplácese suavemente hacia arriba (= animate({scrollTop: 0}, ...)) pero solo si "no hay teclado se muestra "(= if($('input:focus, textarea:focus').length == 0)).

$('input, textarea').live('blur', function(event) {
    window.setTimeout(function() {
        if($('input:focus, textarea:focus').length == 0) {
            $("html, body").animate({ scrollTop: 0 }, 400);
        }
    }, 10)
})

Tenga en cuenta que el período de gracia (= 10) puede ser demasiado corto o que el teclado aún se puede mostrar aunque no esté enfocado inputo no textarea. Por supuesto, si desea que el desplazamiento sea más rápido o más lento, puede ajustar la duración (= 400)

Raul Pinto
fuente
1

realmente trabajó duro para encontrar esta solución, que en resumen busca eventos de enfoque y desenfoque en las entradas, y desplazarse para cambiar selectivamente la posición de la barra fija cuando ocurren los eventos. Esto es a prueba de balas y cubre todos los casos (navegar con <>, desplazarse, botón Listo). Note id = "nav" es mi pie de página fijo div. Puede portar esto fácilmente a js estándar o jquery. Este es un dojo para aquellos que usan herramientas eléctricas ;-)

define (["dojo / ready", "dojo / query",], function (ready, query) {

ready(function(){

    /* This addresses the dreaded "fixed footer floating when focusing inputs and keybard is shown" on iphone 
     * 
     */
    if(navigator.userAgent.match(/iPhone/i)){
        var allInputs = query('input,textarea,select');
        var d = document, navEl = "nav";
        allInputs.on('focus', function(el){
             d.getElementById(navEl).style.position = "static";
        });

        var fixFooter = function(){
            if(d.activeElement.tagName == "BODY"){
                d.getElementById(navEl).style.position = "fixed";
            }
        };
        allInputs.on('blur', fixFooter);
        var b = d.body;
        b.addEventListener("touchend", fixFooter );
    }

});

}); // fin define

httpete
fuente
Esto podría ser increíble ... portar a jQuery / js e informará. Por otro lado, las soluciones en las elecciones de lenguaje de scripts de nicho que requieren portar o agregar herramientas no estándar a un proyecto, previsiblemente, no se encontrarán como universalmente útiles.
ericpeters0n
Esto no funcionará en todos los casos porque lo desplazará a la posición 'estática' del elemento, que podría estar a millas de distancia de la posición original de su entrada, especialmente si está en un contenedor fijo. Si el contenedor tiene una overflow:hiddenregla, no verá su entrada ya que ahora está fuera de la caja.
James M. Lay
1

Este es un problema difícil de "acertar". Puede intentar ocultar el pie de página en el foco del elemento de entrada y mostrarlo en el desenfoque, pero eso no siempre es confiable en iOS. De vez en cuando (una vez de cada diez, por ejemplo, en mi iPhone 4S) el evento de enfoque parece no activarse (o tal vez hay una condición de carrera), y el pie de página no se oculta.

Después de mucho ensayo y error, se me ocurrió esta solución interesante:

<head>
    ...various JS and CSS imports...
    <script type="text/javascript">
        document.write( '<style>#footer{visibility:hidden}@media(min-height:' + ($( window ).height() - 10) + 'px){#footer{visibility:visible}}</style>' );
    </script>
</head>

Esencialmente: use JavaScript para determinar la altura de la ventana del dispositivo, luego cree dinámicamente una consulta de medios CSS para ocultar el pie de página cuando la altura de la ventana se reduzca en 10 píxeles. Debido a que abrir el teclado cambia el tamaño de la pantalla del navegador, esto nunca falla en iOS. Debido a que está usando el motor CSS en lugar de JavaScript, ¡también es mucho más rápido y suave!

Nota: El uso de 'visibilidad: oculto' es menos problemático que 'display: none' o 'position: static', pero su kilometraje puede variar.

Richard Kennard
fuente
1
Es posible que deba cambiar entre la altura y el ancho para arreglar esto para los modos vertical y horizontal.
Neil Monroe
1

Funciona para mi

if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {
    $(document).on('focus', 'input, textarea', function() {
        $('header').css({'position':'static'});
    });
    $(document).on('blur', 'input, textarea', function() {
        $('header').css({'position':'fixed'});
    });
}
ShibinRagh
fuente
1

En nuestro caso, esto se solucionará tan pronto como el usuario se desplace. Así que esta es la solución que hemos estado utilizando para simular un desplazamiento bluren cualquier inputo textarea:

$(document).on('blur', 'input, textarea', function () {
    setTimeout(function () {
        window.scrollTo(document.body.scrollLeft, document.body.scrollTop);
    }, 0);
});
basarat
fuente
1

Mi respuesta es que no se puede hacer.

Veo 25 respuestas pero ninguna funciona en mi caso. Es por eso que Yahoo y otras páginas ocultan el encabezado fijo cuando el teclado está encendido. Y Bing convierte toda la página en no desplazable (overflow-y: hidden).

Los casos discutidos anteriormente son diferentes, algunos tienen problemas al desplazarse, otros en foco o desenfoque. Algunos tienen pie de página fijo o encabezado. Ahora no puedo probar cada combinación, pero podrías terminar dándote cuenta de que no se puede hacer en tu caso.

Szalai Laci
fuente
Esto no responde la pregunta.
neófito
44
Lo hace, ya que la respuesta es que no hay solución.
Szalai Laci
0

Encontré esta solución en Github.

https://github.com/Simbul/baker/issues/504#issuecomment-12821392

Asegúrate de tener contenido desplazable.

// put in your .js file
$(window).load(function(){
    window.scrollTo(0, 1);
});

// min-height set for scrollable content
<div id="wrap" style="min-height: 480px">
  // website goes here
</div>

La barra de direcciones se pliega como un bono adicional.

Leigh Mackay
fuente
0

En caso de que alguien quisiera probar esto. Obtuve lo siguiente trabajando para mí en un pie de página fijo con un campo de entrada en él.

<script>
    $('document').ready(
        function() {
            if (navigator.userAgent.match(/Android/i) || navigator.userAgent.match(/webOS/i) || navigator.userAgent.match(/iPhone/i) || navigator.userAgent.match(/iPad/i)
                  || navigator.userAgent.match(/iPod/i) || navigator.userAgent.match(/BlackBerry/i) || navigator.userAgent.match(/Windows Phone/i)) {
                var windowHeight = $(window).height();
                var documentHeight = $(document).height();

                $('#notes').live('focus', function() {
                    if (documentHeight > windowHeight) {
                        $('#controlsContainer').css({
                            position : 'absolute'
                        });
                        $("html, body").animate({
                            scrollTop : $(document).height()
                        }, 1);
                    }
                });
                $('#notes').live('blur', function() {
                    $('#controlsContainer').css({
                        position : 'fixed'
                    });
                    $("html, body").animate({
                        scrollTop : 0
                    }, 1);
                });
            }
        });
</script>
Bernardo
fuente
0

Tengo el mismo problema. Pero me di cuenta de que la posición fija solo se retrasa y no se rompe (al menos para mí). Espere de 5 a 10 segundos y vea si el div vuelve a ajustarse a la parte inferior de la pantalla. Creo que no es un error, sino una respuesta retrasada cuando el teclado está abierto.

Philip
fuente
0

Intenté todos los enfoques de este hilo, pero si no me ayudaron, lo hicieron aún peor. Al final, decidí forzar el dispositivo a perder el foco:

$(<selector to your input field>).focus(function(){
    var $this = $(this);
    if (<user agent target check>) {
        function removeFocus () {
            $(<selector to some different interactive element>).focus();
            $(window).off('resize', removeFocus);
        }
        $(window).on('resize', removeFocus);
    }
});

y funcionó de maravilla y arregló mi formulario de inicio de sesión adhesivo.

Por favor, tenga en cuenta:

  1. El código JS anterior es solo para presentar mi idea, para ejecutar este fragmento, reemplace los valores en llaves angulares (<>) con los valores apropiados para su situación.
  2. Este código está diseñado para funcionar con jQuery v1.10.2
Anton Boritskiy
fuente
0

Esto sigue siendo un gran error para cualquier página HTML con más altos Bootstrap Modals en iOS 8.3. Ninguna de las soluciones propuestas anteriormente funcionó y después de hacer zoom en cualquier campo debajo del pliegue de un modal alto, Mobile Safari y / o WkWebView moverían los elementos fijos a donde estaba ubicado el desplazamiento del cuerpo HTML, dejándolos desalineados con el lugar donde realmente estaban donde Dispuesto.

Para solucionar el error, agregue un detector de eventos a cualquiera de sus entradas modales como:

$(select.modal).blur(function(){
  $('body').scrollTop(0);
});

Supongo que esto funciona porque forzar la altura de desplazamiento del cuerpo HTML vuelve a alinear la vista real con el lugar donde iOS 8 WebView espera que estén los contenidos del div modal fijo.

diseñador de profundidad
fuente
0

Si alguien estaba buscando una ruta completamente diferente (como si ni siquiera quisieras fijar este div "pie de página" mientras te desplazas pero solo quieres que el div permanezca en la parte inferior de la página), puedes establecer la posición del pie de página como relativo.

Eso significa que incluso si el teclado virtual aparece en su navegador móvil, su pie de página permanecerá anclado en la parte inferior de la página, sin tratar de reaccionar ante el espectáculo o el cierre del teclado virtual.

Obviamente, se ve mejor en Safari si la posición está fija y el pie de página sigue la página a medida que se desplaza hacia arriba o hacia abajo, pero debido a este extraño error en Chrome, terminamos cambiando a solo hacer que el pie de página sea relativo.

Terry Bu
fuente
0

Ninguna de las soluciones de desplazamiento parecía funcionar para mí. En cambio, lo que funcionó es establecer la posición del cuerpo como fija mientras el usuario edita el texto y luego restaurarlo a estático cuando el usuario haya terminado. Esto evita que Safari recorra tu contenido. Puede hacer esto en el foco / desenfoque de los elementos (se muestra a continuación para un solo elemento, pero podría ser para todas las entradas, áreas de texto), o si un usuario está haciendo algo para comenzar a editar, como abrir un modal, puede hacer sobre esa acción (por ejemplo, modal abrir / cerrar).

$("#myInput").on("focus", function () {
    $("body").css("position", "fixed");
});

$("#myInput").on("blur", function () {
    $("body").css("position", "static");
});
Scott Semyan
fuente
0

iOS9: mismo problema.

TLDR - fuente del problema. Para la solución, desplácese hacia abajo

Tenía un formulario en un position:fixediframe con id = 'subscribe-popup-frame'

Según la pregunta original, en el enfoque de entrada, el iframe iría a la parte superior del documento en lugar de a la parte superior de la pantalla.

El mismo problema no ocurrió en el modo de desarrollo de safari con el agente de usuario establecido en un idevice. Por lo tanto, parece que el problema es causado por el teclado virtual iOS cuando aparece.

Obtuve cierta visibilidad de lo que estaba sucediendo al registrar la posición del iframe en la consola (por ejemplo $('#subscribe-popup-frame', window.parent.document).position()) y desde allí pude ver que iOS parecía estar configurando la posición del elemento{top: -x, left: 0} cuando apareció el teclado virtual (es decir, enfocado en el elemento de entrada).

Entonces, mi solución fue tomar esa molestia -x, revertir el signo y luego usar jQuery para agregar esa topposición nuevamente al iframe. Si hay una solución mejor, me encantaría escucharla, pero después de probar una docena de enfoques diferentes, fue la única que funcionó para mí.

Inconveniente: necesitaba establecer un tiempo de espera de 500 ms (tal vez menos funcionaría, pero quería estar seguro) para asegurarme de capturar el xvalor final después de que iOS había hecho mal con la posición del elemento. Como resultado, la experiencia es muy desigual. . . Pero al menos funciona

Solución

        var mobileInputReposition = function(){
             //if statement is optional, I wanted to restrict this script to mobile devices where the problem arose
            if(screen.width < 769){
                setTimeout(function(){
                    var parentFrame = $('#subscribe-popup-frame',window.parent.document);
                    var parentFramePosFull = parentFrame.position();
                    var parentFramePosFlip = parentFramePosFull['top'] * -1;
                    parentFrame.css({'position' : 'fixed', 'top' : parentFramePosFlip + 'px'});
                },500);
            }    
        }   

Entonces solo llame mobileInputRepositiona algo como $('your-input-field).focus(function(){})y$('your-input-field).blur(function(){})

martellalex
fuente