Entiendo que el móvil de safari tiene un montón de bichos en elementos fijos, pero la mayoría de los que he conseguido mi diseño funcione correctamente hasta que he añadido un muy necesitado de entrada de texto para la navegación fija en la parte inferior. Ahora, cuando el usuario se centra en el elemento de entrada de texto y el teclado virtual aparece, mi navegación, que de lo contrario siempre se fija en la parte inferior de la página, salta a un lugar extraño en el medio de la página.

¿Cómo puedo detener mi navegación fija de movimiento como este, cuando se abre el teclado virtual en Mobile Safari?

Me gustaría añadir algunos de mi código para este post, pero yo no estaría seguro de por dónde empezar. Que la navegación se fija en la parte inferior y se coloca a la izquierda y la inferior 0 y 100% de ancho. A partir de ahí, no sé lo que está pasando, sólo puedo asumir que es un móvil de safari error.

También parece perder su posición fija y se convierten en relativos, mientras que sólo el elemento de entrada de texto se enfoca, y el teclado virtual está abierta.

  • Yo acabo de hacer ahora, sin suerte. Es algo específico que hacer con mobile safari, o IOS. Por la razón que sea se elimina la posición fija, mientras que el teclado, luego todo vuelve a la posición normal y atributos una vez que el teclado está cerrado. Además de por qué nunca se mueve de elementos fijos como este.
  • Sería la adición de cualquier estilo, por ejemplo,margin-top, top, bottom, a la :active o :focus pseudo-elementos de trabajo?
  • La adición de un negativo margine parte inferior de 215px, que es la altura a la que está siendo empujado hacia arriba, es la última cosa que he probado, y de nuevo sin suerte.
  • Bueno, supongo que sería un Safari error. No hay nada más puedo pensar de otra que esperar a que Apple solucionarlo. Edit: he intentado bottom: -215px?
  • Posibles duplicados de varias preguntas. Consulte gist.github.com/avesus/… para obtener más detalles.
  • La cuestión es suficientemente antigua como el software ha sido actualizado tantas veces me cabe duda, estas preguntas tienen nada que ver con sus quejas, o probablemente el uno con el otro.

InformationsquelleAutor Eric | 2013-03-07

11 Comentarios

  1. 19

    http://dansajin.com/2012/12/07/fix-position-fixed/ esta es una de las soluciones propuestas. Parece que vale la pena un tiro.

    En resumen: conjunto de fixed elementos para position:absolute cuando cualquier entrada es focused y restablecerlos cuando ese elemento es blurrojo

    .header { 
        position: fixed; 
    } 
    .footer { 
        position: fixed; 
    } 
    .fixfixed .header, 
    .fixfixed .footer { 
        position: absolute; 
    } 

    y

    if ('ontouchstart' in window) {
        /* cache dom references */ 
        var $body = $('body'); 
    
        /* bind events */
        $(document)
        .on('focus', 'input', function() {
            $body.addClass('fixfixed');
        })
        .on('blur', 'input', function() {
            $body.removeClass('fixfixed');
        });
    }
    • Ah, que era una fácil e inteligente truco. Gracias por compartir, trabajó para mí.
    • Dan Sajin sitio web no tomar el cuidado del problema en Chrome-el navegador en dispositivos IOS. Pero funciona realmente bien para Safari.
    • bfred plese ver este enlace stackoverflow.com/questions/38341941/…
    • también estoy intentando fija el encabezado cuando se enfoca campo de texto, pero no estamos resolviendo el problema
  2. 15

    Las soluciones en la parte superior son algunas maneras de ir y arreglar el problema, pero creo que la adición extra clase css o el uso de moderniz nos están complicando las cosas.

    Si quieres una solución simple, aquí es un no modernizr no-extra-css pero puro jquery solución y de trabajo en todos los dispositivos y navegadores que uso esta revisión en todos mis proyectos

    if ('ontouchstart' in window) {
        $(document).on('focus', 'textarea,input,select', function() {
            $('.navbar.navbar-fixed-top').css('position', 'absolute');
        }).on('blur', 'textarea,input,select', function() {
            $('.navbar.navbar-fixed-top').css('position', '');
        });
    }
    • Este fue uno de los más simples correcciones que he encontrado que funciona mejor universalmente. Buen trabajo!
    • gran sencilla solución sólida 🙂 Acaba de agregar [contenteditable] a los objetivos, si usted tiene contenteditable divs
    • Esto funciona, pero hace que el encabezado de flash cada vez que el teclado aparece.
  3. 5

    He tenido un problema similar, pero he encontrado una solución mediante la adición de la siguiente clase css del elemento body en el foco de entrada y luego se retira de nuevo en unfocus:

    .u-oh {
        overflow: hidden;
        height: 100%;
        width: 100%;
        position: fixed;
    }
    • Las otras soluciones a la izquierda de mi pie a mitad de camino oculto debajo del teclado Y desplaza la pantalla a la parte inferior, pero funcionó a la perfección!
  4. 3

    De tomar de lo que sylowgreen hizo, la clave es fijar la body entrando en el input. Por lo tanto:

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

    Añadir javascript como este:

    $(function() {
      var $body;
      if ('ontouchstart' in window) {
        $body = $("body");
        document.addEventListener('focusin', function() {
          return $body.addClass("fixfixed");
        });
        return document.addEventListener('focusout', function() {
          $body.removeClass("fixfixed");
          return setTimeout(function() {
            return $(window).scrollLeft(0);
          }, 20);
        });
      }
    });

    y agregar la clase como esta:

    .fixfixed header{ 
        position: absolute; 
    } 

    puede hacer referencia a este artículo: http://dansajin.com/2012/12/07/fix-position-fixed/

  6. 1

    Me gusta mucho la solución anterior. Yo empaquetan en un pequeño plugin de jQuery para que yo pudiera:

    • Establece que los padres obtiene la clase
    • Conjunto de elementos que este se aplica (no se olvide «textarea» y «select»).
    • Conjunto de lo que los padres nombre de la clase es
    • Permiten ser encadenado
    • Le permiten ser utilizado varias veces

    Ejemplo de código:

    $.fn.mobileFix = function (options) {
        var $parent = $(this),
        $fixedElements = $(options.fixedElements);
    
        $(document)
        .on('focus', options.inputElements, function(e) {
            $parent.addClass(options.addClass);
        })
        .on('blur', options.inputElements, function(e) {
            $parent.removeClass(options.addClass);
    
            //Fix for some scenarios where you need to start scrolling
            setTimeout(function() {
                $(document).scrollTop($(document).scrollTop())
            }, 1);
        });
    
        return this; //Allowing chaining
    };
    
    //Only on touch devices
    if (Modernizr.touch) {
        $("body").mobileFix({ //Pass parent to apply to
            inputElements: "input,textarea,select", //Pass activation child elements
            addClass: "fixfixed" //Pass class name
        });
    }
  7. 1

    Yo uso este script jQuery:

    var focus = 0;
    var yourInput = $(".yourInputClass");
    yourInput.focusin(function(){
        if(!focus) {
            yourInput.blur();
            $("html, body").scrollTop($(document).height());
            focus = 1;
        }
        if(focus) {
            yourInput.focus();
            focus = 0;
        }
    });

    Funciona a la perfección para mí.

    • Este es el más cercano de la solución hasta ahora para mí, ninguno de los otros parecen funcionar. Esto funciona para mí, pero a veces la entrada está a la izquierda acoplado en la parte inferior y el teclado virtual que se superpone a ella.
  8. 1

    La focusin y focusout eventos parecen ser más adecuados para este problema que el focus y blur eventos ya que la anterior burbuja hasta el elemento raíz. Ver esta respuesta en TAN.

    Personalmente puedo usar AngularJS, por lo que he implementado es como este:

    $window.document.body.addEventListener('focusin', function(event) {
        var element = event.target;
        var tagName = element.tagName.toLowerCase();
        if(!$rootScope.inputOverlay && (tagName === 'input' || tagName === 'textarea' || tagName === 'select')) {
            $rootScope.$apply(function() {
                $rootScope.inputOverlay = true;
            });
        }
    });
    $window.document.body.addEventListener('focusout', function() {
        if($rootScope.inputOverlay) {
            $rootScope.$apply(function() {
                $rootScope.inputOverlay = false;
            });
        }
    });

    Nota: estoy condicionalmente ejecutar esta secuencia de comandos si este es mobile Safari.

    Pongo un ng-class atributo en mi barra de navegación:

    <div class="navbar navbar-default navbar-fixed-top" ng-class="{'navbar-absolute': inputOverlay}">

    utilizando el siguiente CSS:

    .navbar-absolute {
        position: absolute !important;
    }

    Usted puede leer más acerca de focusin aquí y focusout aquí.

  9. 0

    Probar este. Funciona. Acabo de probarlo.

    $(document).on('focus','input', function() {
        setTimeout(function() {
            $('#footer1').css('position', 'absolute');
            $('#header1').css('position', 'absolute');
        }, 0);
    });
    $(document).on('blur','input', function() {
        setTimeout(function() {
            $('#footer1').css('position', 'fixed');
            $('#header1').css('position', 'fixed');
        }, 800);
    });
  10. 0

    Ninguna de estas soluciones funciona para mí porque mi DOM es complicado y me han dinámica infinita de desplazamiento de páginas, así que tuve que crear mi propia.

    De fondo: estoy usando un encabezado fijo y un elemento más abajo que se pega debajo de la misma una vez que el usuario se desplaza de que muy abajo. Este elemento tiene un campo de búsqueda. Además, he páginas dinámicas añadido durante adelante y hacia atrás de desplazamiento.

    Problema: En iOS, en cualquier momento el usuario hace clic en la entrada en el elemento fijo, el navegador desplácese a la parte superior de la página. Esto no sólo causó un comportamiento no deseado, también se activa mi página dinámica añadir en la parte superior de la página.

    Solución de espera: de desplazamiento No en iOS (ninguno) cuando el usuario hace clic en la entrada en la pegajosa elemento.

    Solución:

         /*Returns a function, that, as long as it continues to be invoked, will not
    be triggered. The function will be called after it stops being called for
    N milliseconds. If `immediate` is passed, trigger the function on the
    leading edge, instead of the trailing.*/
    function debounce(func, wait, immediate) {
    var timeout;
    return function () {
    var context = this, args = arguments;
    var later = function () {
    timeout = null;
    if (!immediate) func.apply(context, args);
    };
    var callNow = immediate && !timeout;
    clearTimeout(timeout);
    timeout = setTimeout(later, wait);
    if (callNow) func.apply(context, args);
    };
    };
    function is_iOS() {
    var iDevices = [
    'iPad Simulator',
    'iPhone Simulator',
    'iPod Simulator',
    'iPad',
    'iPhone',
    'iPod'
    ];
    while (iDevices.length) {
    if (navigator.platform === iDevices.pop()) { return true; }
    }
    return false;
    }
    $(document).on("scrollstop", debounce(function () {
    //console.log("Stopped scrolling!");
    if (is_iOS()) {
    var yScrollPos = $(document).scrollTop();
    if (yScrollPos > 200) { //200 here to offset my fixed header (50px) and top banner (150px)
    $('#searchBarDiv').css('position', 'absolute');
    $('#searchBarDiv').css('top', yScrollPos + 50 + 'px'); //50 for fixed header
    }
    else {
    $('#searchBarDiv').css('position', 'inherit');
    }
    }
    },250,true));
    $(document).on("scrollstart", debounce(function () {
    //console.log("Started scrolling!");
    if (is_iOS()) {
    var yScrollPos = $(document).scrollTop();
    if (yScrollPos > 200) { //200 here to offset my fixed header (50px) and top banner (150px)
    $('#searchBarDiv').css('position', 'fixed');
    $('#searchBarDiv').css('width', '100%');
    $('#searchBarDiv').css('top', '50px'); //50 for fixed header
    }
    }
    },250,true));

    Requisitos: JQuery mobile es necesaria para la startsroll y stopscroll funciones de trabajo.

    De rebote se incluye para suavizar cualquier retraso creado por el pegajoso elemento.

    Probado en iOS10.

  11. -1

    Yo no estaba teniendo suerte con la solución propuesta por Dan Sajin. Quizás el error ha cambiado desde que se escribió la entrada en el blog, pero en iOS 7.1, el error será siempre la superficie cuando se cambia la posición de la espalda fija después de la entrada es borrosa, incluso si se demora hasta que el software del teclado se oculta completamente. La solución que se me vino a implica a la espera de un touchstart evento en lugar de la blur evento desde el elemento fijo siempre se asiente en su posición correcta cuando la página se desplaza.

    if (Modernizr.touch) {
    var $el, focused;
    $el = $('body');
    focused = false;
    $(document).on('focus', 'input, textarea, select', function() {
    focused = true;
    $el.addClass('u-fixedFix');
    }).on('touchstart', 'input, textarea, select', function() {
    //always execute this function after the `focus` handler:
    setTimeout(function() {
    if (focused) {
    return $el.removeClass('u-fixedFix');
    }
    }, 1);
    });
    }

    HTH

    • Lo que css no la clase u-fixedFix contienen? Esto no funciona en mi iPad (iOS 7.1.2 – 11D257) como la de ahora.
    • Las mismas reglas de la clase que se usa en la respuesta por wxy112233, es decir. position: absolute.

Dejar respuesta

Please enter your comment!
Please enter your name here