135 votes

iOS 5 positionnement fixe et clavier virtuel

J'ai un site web mobile qui a un div épinglés sur le bas de l'écran via la position:fixed. Tous fonctionne bien dans iOS 5 (je suis en essais sur un iPod Touch) jusqu'à ce que je suis sur une page avec un formulaire. Quand je tape dans un champ de saisie et le clavier virtuel apparaît, tout à coup la position fixe de mon div est perdu. La div maintenant défile avec la page tant que le clavier est visible. Une fois que je clique sur Terminé pour fermer le clavier, la div revient à sa position au bas de l'écran et obéit à la position:fixe la règle.

Quelqu'un d'autre a connu ce genre de comportement? Est-ce prévu? Merci.

49voto

Nick Retallack Points 5994

J'ai eu ce problème dans mon application. Voici comment je travaille autour de ça:

 input.on('focus', function(){
    header.css({position:'absolute'})
    $(window).scrollTop(0)    
})
input.on('blur', function(){
    header.css({position:'fixed'})
})
 

Je fais juste défiler vers le haut et le positionne là-bas, de sorte que l'utilisateur iOS ne remarque rien de bizarre. Enveloppez ceci dans une détection d'agent d'utilisateur afin que d'autres utilisateurs n'obtiennent pas ce comportement.

15voto

ds111 Points 167

J'ai eu un problème d'ipad légèrement différent où le clavier virtuel a poussé mon affichage vers le haut de l'écran. Ensuite, après la fermeture du clavier virtuel par l’utilisateur, ma fenêtre d’affichage était toujours hors écran. Dans mon cas, j'ai fait quelque chose comme ceci:

 var el = document.getElementById('someInputElement');
function blurInput() {
    window.scrollTo(0, 0);
}
el.addEventListener('blur', blurInput, false);
 

14voto

Hatch Points 130

C'est le code que nous utilisons pour résoudre les problèmes avec ipad. Il détecte essentiellement les écarts entre l'offset et la position de défilement, ce qui signifie que «fixe» ne fonctionne pas correctement.

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

12voto

Riley Dutton Points 2041

La position fixe, les éléments n'ont tout simplement pas de mise à jour de leur position lorsque le clavier est en place. J'ai trouvé que par ruse Safari en pensant que la page a redimensionné, cependant, les éléments se re-positionner eux-mêmes. Il n'est pas parfait, mais au moins vous n'avez pas à vous soucier de commutation de 'position: absolute' et le suivi des modifications vous-même.

Le code suivant juste à l'écoute lorsque l'utilisateur est susceptible d'être à l'aide du clavier (à cause d'une entrée en cours de concentré), et jusqu'à ce qu'il entend un flou juste écoute les événements de défilement et fait ensuite la redimensionner truc. Semble fonctionner assez bien pour moi donc loin.

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

6voto

Jory Cunningham Points 499

Juste au cas où quelqu'un arriverait sur ce sujet comme je l'ai fait en recherchant ce problème. J'ai trouvé ce fil utile pour stimuler ma réflexion sur cette question.

C'était ma solution pour cela sur un projet récent. Il suffit de changer la valeur de "targetElem" pour un sélecteur jQuery qui représente votre en-tête.

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

};
 

Il y a un petit retard dans le correctif, car iOS arrête la manipulation du DOM pendant le défilement, mais il fait l'affaire ...

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X