9
votes

Position fixe Div gèle à la page (iPad)

J'ai un site Web ASP.NET que je consomme pour être pris en charge sur iPad. Lorsque je me concentre sur un élément d'entrée et que le clavier apparaît, la position fixe DIV (qui fait défiler normalement avec la page) apparaîtra à la page une distance d'équivalent à la quantité du clavier et gelez-la pendant la durée de la processus d'entrée. Une fois que le clavier est tombé en arrière, la div se glisse en place et se comporte normalement à nouveau. Je teste sur iOS5 de sorte que la position: fixe doit être prise en charge.

Est-ce un problème connu? Quelqu'un a-t-il rencontré cela et de la traiter avant? Je n'arrive pas à trouver quoi que ce soit sur ceci.


0 commentaires

3 Réponses :


18
votes

Le positionnement fixe est cassé sur iOS5 / iOS6 / iOS7.

Edit 3: voir le lien vers une solution de fonctionnement près de la fin de cette réponse pour iOS8.

Position: Correction est brisé lorsque:

a) La page est zoomée

ou

b) les spectacles du clavier sur l'iPad / iPhone (en raison d'une entrée en entrée).

Vous pouvez voir les bugs vous-même dans jsbin.com/icibaz/3 en ouvrant le lien et zoomer ou donner la mise au point d'entrée. Vous pouvez modifier le Modifier le HTML vous-même.

notes sur les bugs (a) et (b):

  1. A DIV fixe avec TOP: 0PX; Gauche: 0px; montrera dans la mauvaise position (ci-dessus ou sous le haut de l'écran) lors de la mise au point de la mise au point et du clavier.

  2. Le problème semble avoir quelque chose à voir avec le centrage automatique de l'entrée à l'écran (changer de fenêtre.PageYoffset).

  3. Il semble s'agir d'un défaut de calcul et non d'un défaut de redessinement: si vous forcez le top pour modifier (par exemple, la commutation entre 0PX et 1PX) sur l'événement OnScroll, vous pouvez Voir le déménagement divisé par un pixel, mais il reste au mauvais endroit.

  4. Une solution que j'ai utilisée précédemment est de Masquer le DIV fixe lorsqu'une entrée reçoit la mise au point - Voir l'autre réponse que j'ai écrite.

  5. La Div fixe semble être bloquée à la même position absolue de la page qu'il était à l'époque où le clavier s'est ouvert.

  6. peut-être peut-être changer le div au positionnement absolu lorsqu'une entrée a la mise au point? Edit 3: Voir le commentaire en bas à l'aide de cette solution. Ou peut-être enregistrer les valeurs de pageXOffset / pageOffset avant que le clavier ne soit ouverte et dans un événement Onscroll, calculez la différence entre ces valeurs et les valeurs actuelles de la pageXOffset / pagesOffset (actuelle une fois que le clavier est ouvert) et compenser la DIV fixe par cette différence.

  7. Il semble y avoir un problème différent avec un positionnement fixe si la page est zoomée - essayez-la ici (Aussi bonnes informations ici sur la prise en charge de Android pour les commentaires fixes).

    EDIT 1: Pour reproduire Utilisez JSBIN (pas JSFIDDLE) et utilisez la vue plein écran de JSBIN (pas la page d'édition). Évitez Jsfiddle (et modifier la vue de JSBIN) car ils mettent le code à l'intérieur d'un iframe qui provoque des interférences avec un positionnement fixe et une pageOffset.

    Edit 2: iOS 6 et iOS 7 Safari mobile Position: fixe; a toujours les mêmes problèmes - vraisemblablement ils sont par conception!

    Editer 3: une solution de travail pour (b) est lorsque l'entrée est mise au point, modifiez l'en-tête en position absolue, puis définissez le haut de l'en-tête de l'événement de défilement de la page par exemple . Cette solution:

    • utilise un positionnement fixe lorsque l'entrée n'est pas focalisée (à l'aide de la fenêtre.Scroll a une gigue terrible).
    • Ne permettez pas à Pinch-zoom (éviter le bogue (A) ci-dessus).
    • utilise un positionnement absolu et une fenêtre.PageYoffset une fois qu'une entrée se concentre (donc en-tête est correctement positionnée).
    • Si défilé pendant que l'entrée est mise au point, définissez style.top à égale pageOffset (l'en-tête gênera quelque peu en raison du retard des événements Onscroll, même sur IOS8).
    • Si vous utilisez UiWebView au sein d'une application sur iOS8 ou à l'aide de <= iOS7, si vous faites défiler lorsque l'entrée est mise au point, l'en-tête sera super gênée car Onscroll n'est pas tiré sur les finitions de défilement.
    • retourne à l'en-tête de position fixe une fois que l'entrée perd la mise au point (exemple utilise INPUT.Onblur, mais probablement englental à utiliser document.body.onfocus).
    • Attention à la convivialité échoue que si l'en-tête est trop volumineuse, l'entrée peut être obstruée / couverte.
    • Je n'ai pas pu arriver à travailler pour un pied de page en raison de bugs dans la page de la page IOS / Viewport lorsque le clavier montrent.
    • Modifier l'exemple en utilisant http://jsbin.com/xujofoze/4/edit et voir en utilisant http://output.jsbin.com/xujofoze/4/quiet

5 commentaires

Il s'avère que ceci est un bug iOS, je quitterai ce problème pour l'instant, mais vos suggestions sont valides, donc je vais marquer cette réponse correcte


JAS, est-il possible de donner le lien pour l'URL de l'émission de bug iOS?


Je n'ai pas regardé ce qui a été corrigé dans iOS6, mais au moins un bogue supplémentaire a été ajouté: igstudio.blogspot.com/2012/09/positionfixed-in-ios-6.html (je soupçonne également de donner à la propriété Div une propriété CSS qui force à avoir du matériel accéléré La composition pourrait également le réparer).


IOS 8 Le bogue est toujours ici mais agit maintenant différent. Lorsque vous modifiez la position des divs absolus, ne restez pas au même positionnement.


@nicolas L'exemple de iOS8 référencé ci-dessus semble fonctionner correctement. Essayez ici: sortie.jsbin.com/xujofoze/4/quiet



0
votes

Pour mes besoins, j'ai trouvé plus facile d'utiliser un en-tête positionné absolu, cachez-le avant de le faire défiler et de le montrer lorsque vous avez terminé le défilement (j'ai besoin du même code pour prendre en charge iOS4 et Android).

à mes fins, je me cache L'en-tête sur un événement TouchStart CODE> et le montrer à nouveau sur touchend code> ou défilement code> Evénement (plus des minuteries pour améliorer la réactivité / réduction de la vaccination). Il clignote, mais est le meilleur compromis que je pouvais trouver. On peut détecter le début du défilement à l'aide de l'événement code> TouchMove CODE> (JQuery en fait ceci), mais j'ai trouvé touchmove code> n'a pas fonctionné aussi pour moi parce que: p>

  • régulièrement, l'iPad ne parvient pas à faire une repeindre avant le défilement (c'est-à-dire que l'en-tête absolu reste coincé - même si le Top code> a été modifié avant le démarrage du défilement). P> LI>

  • Lorsqu'un élément d'entrée se concentre, l'iPad se concentre automatiquement l'élément, mais l'événement ScrollStart ne doit pas être tiré (car pas de motif de contact si juste cliquez sur code> une entrée). li> OL>

    La mise en œuvre d'un en-tête fixe sur iOS5 pourrait être améliorée en utilisant une approche hybride du positionnement fixe et absolu: p>

    • Positionnement fixe utilisé pour iOS5 jusqu'à ce qu'une entrée soit mise au point. P> LI>

    • Lorsqu'une entrée reçoit la mise au point (clavier montrant), passez au code de positionnement absolu IOS4. P> LI>

    • Lorsque le clavier est fermé, reportez-vous au positionnement fixe. P> LI> ul>

      code pour détecter lorsque le clavier est fermé (par exemple, l'utilisation de la clé de masque du clavier) consiste à enregistrer l'événement DOMFOCUSOUT CODE> dans le document document code> et faire quelque chose comme le code suivant. Le délai d'attente est nécessaire car l'événement DOMFOCUSOUT DOMFOCUSOUT peut tirer entre le moment où un élément obtient la mise au point et une autre perd. P> xxx pré>

      mon code d'en-tête fixe est quelque chose Comme: p> xxx pré>

      jQuery mobile prend en charge les événements ScrollStart et ScrollStop: p>

      var supportTouch = $.support.touch,
          scrollEvent = "touchmove scroll",
          touchStartEvent = supportTouch ? "touchstart" : "mousedown",
          touchStopEvent = supportTouch ? "touchend" : "mouseup",
          touchMoveEvent = supportTouch ? "touchmove" : "mousemove";
      
      function triggerCustomEvent( obj, eventType, event ) {
          var originalType = event.type;
          event.type = eventType;
          $.event.handle.call( obj, event );
          event.type = originalType;
      }
      
      // also handles scrollstop
      $.event.special.scrollstart = {
      
          enabled: true,
      
          setup: function() {
      
              var thisObject = this,
                  $this = $( thisObject ),
                  scrolling,
                  timer;
      
              function trigger( event, state ) {
                  scrolling = state;
                  triggerCustomEvent( thisObject, scrolling ? "scrollstart" : "scrollstop", event );
              }
      
              // iPhone triggers scroll after a small delay; use touchmove instead
              $this.bind( scrollEvent, function( event ) {
      
                  if ( !$.event.special.scrollstart.enabled ) {
                      return;
                  }
      
                  if ( !scrolling ) {
                      trigger( event, true );
                  }
      
                  clearTimeout( timer );
                  timer = setTimeout(function() {
                      trigger( event, false );
                  }, 50 );
              });
          }
      };
      


  • 0 commentaires

    0
    votes

    Ceci est un peu encore un problème dans iOS13 (lorsqu'un texte long est supprimé dans le champ «Texarea», l'en-tête fixe saute au début de ce champ «Texarea», obstruant la vue), donc je pensais que je partage mon Correction rapide:

    Puisque mon pied de page est plutôt grand, je suis allé sans JS et il suffit d'ajouter un plus grand index Z au pied de page que ce que l'en-tête fixe a. Hors de vue, hors de l'esprit.


    0 commentaires