Dans IOS8 Safari, il y a un nouveau bogue avec la position corrigée.
Si vous concentrez une zone de texte qui se trouve dans un panneau fixe, safari vous fera défiler vers le bas de la page.
Cela rend toutes sortes d'interfaces utilisateur impossibles à utiliser, car vous n'avez aucun moyen de saisir du texte dans des zones de texte sans faire défiler votre page jusqu'en bas et perdre votre place.
Existe-t-il un moyen de contourner proprement ce bogue?
#a {
height: 10000px;
background: linear-gradient(red, blue);
}
#b {
position: fixed;
bottom: 20px;
left: 10%;
width: 100%;
height: 300px;
}
textarea {
width: 80%;
height: 300px;
}
<html>
<body>
<div id="a"></div>
<div id="b"><textarea></textarea></div>
</body>
</html>
Réponses:
Sur la base de cette bonne analyse de ce problème, j'ai utilisé ceci dans
html
et desbody
éléments en css:Je pense que cela fonctionne très bien pour moi.
la source
transform: translateZ(0);
partir de stackoverflow.com/questions/7808110/…La meilleure solution que je pourrais trouver est de passer à l'utilisation
position: absolute;
de la mise au point et de calculer la position à laquelle il se trouvait lorsqu'il était utiliséposition: fixed;
. L'astuce est que l'focus
événement se déclenche trop tard, alorstouchstart
doit être utilisé.La solution dans cette réponse imite de très près le comportement correct que nous avions dans iOS 7.
Exigences:
le
body
élément doit avoir un positionnement afin d'assurer un bon positionnement lorsque l'élément passe en positionnement absolu.Le code ( exemple en direct ):
Le code suivant est un exemple de base pour le cas de test fourni et peut être adapté à votre cas d'utilisation spécifique.
Voici le même code sans le hack pour comparaison .
Caveat:
Si la
position: fixed;
élément a d'autres éléments parents avec un positionnement en plusbody
, le passage àposition: absolute;
peut avoir un comportement inattendu. En raison de la nature deposition: fixed;
cela, ce n'est probablement pas un problème majeur, car l'imbrication de tels éléments n'est pas courante.Recommandations:
Bien que l'utilisation de l'
touchstart
événement filtrera la plupart des environnements de bureau, vous souhaiterez probablement utiliser le reniflage de l'agent utilisateur afin que ce code ne s'exécute que pour l'iOS 8 cassé, et non pour d'autres appareils tels qu'Android et les anciennes versions d'iOS. Malheureusement, nous ne savons pas encore quand Apple résoudra ce problème dans iOS, mais je serais surpris qu'il ne soit pas résolu dans la prochaine version majeure.la source
J'ai trouvé une méthode qui fonctionne sans avoir besoin de changer de position absolue!
Code complet non commenté
Le décomposer
Vous devez d'abord avoir le champ de saisie fixe vers le haut de la page dans le HTML (c'est un élément fixe, il devrait donc être sémantiquement logique de l'avoir près du haut de toute façon):
Ensuite, vous devez enregistrer la position de défilement actuelle dans des variables globales:
Ensuite, vous avez besoin d'un moyen de détecter les appareils iOS afin que cela n'affecte pas les choses qui n'ont pas besoin du correctif (fonction tirée de https://stackoverflow.com/a/9039885/1611058 )
Maintenant que nous avons tout ce dont nous avons besoin, voici le correctif :)
la source
J'ai pu résoudre ce problème pour les entrées sélectionnées en ajoutant un écouteur d'événement aux éléments de sélection nécessaires, puis en faisant défiler d'un décalage d'un pixel lorsque la sélection en question gagne le focus.
Ce n'est pas nécessairement une bonne solution, mais c'est beaucoup plus simple et plus fiable que les autres réponses que j'ai vues ici. Le navigateur semble re-rendre / recalculer la position: fixe; attribut basé sur le décalage fourni dans la fonction window.scrollBy ().
la source
Tout comme Mark Ryan Sallee l'a suggéré, j'ai trouvé que changer dynamiquement la hauteur et le débordement de mon élément d'arrière - plan est la clé - cela ne donne à Safari rien sur quoi faire défiler.
Donc, une fois l'animation d'ouverture du modal terminée, changez le style de l'arrière-plan:
Lorsque vous fermez le modal, changez-le de nouveau:
Alors que d'autres réponses sont utiles dans des contextes plus simples, mon DOM était trop compliqué (grâce à SharePoint) pour utiliser l'échange de position absolue / fixe.
la source
Propre? non.
J'ai récemment eu ce problème moi-même avec un champ de recherche fixe dans un en-tête collant, le mieux que vous puissiez faire pour le moment est de garder la position de défilement dans une variable à tout moment et, lors de la sélection, de rendre la position de l'élément fixe absolue au lieu de fixe avec un haut position basée sur la position de défilement du document.
C'est cependant très moche et entraîne toujours d'étranges allers-retours avant d'atterrir au bon endroit, mais c'est le plus proche que je puisse obtenir.
Toute autre solution impliquerait de remplacer les mécanismes de défilement par défaut du navigateur.
la source
Ceci est maintenant corrigé dans iOS 10.3!
Les piratages ne devraient plus être nécessaires.
la source
Je n'ai pas traité de ce bogue particulier, mais peut-être mettre un débordement: hidden; sur le corps lorsque la zone de texte est visible (ou simplement active, selon votre conception). Cela peut avoir pour effet de ne pas donner au navigateur quelque part "en bas" pour faire défiler.
la source
Une solution possible serait de remplacer le champ de saisie.
codepen
la source
Aucune de ces solutions n'a fonctionné pour moi car mon DOM est compliqué et j'ai des pages de défilement infinies dynamiques, j'ai donc dû créer les miennes.
Contexte: J'utilise un en-tête fixe et un élément plus bas qui reste en dessous une fois que l'utilisateur fait défiler aussi loin vers le bas. Cet élément a un champ d'entrée de recherche. De plus, j'ai des pages dynamiques ajoutées lors du défilement vers l'avant et vers l'arrière.
Problème: sous iOS, chaque fois que l'utilisateur cliquait sur l'entrée dans l'élément fixe, le navigateur défilait jusqu'en haut de la page. Cela a non seulement provoqué un comportement indésirable, mais également déclenché l'ajout de ma page dynamique en haut de la page.
Solution attendue: pas de défilement dans iOS (aucun du tout) lorsque l'utilisateur clique sur l'entrée dans l'élément collant.
Solution:
Exigences: JQuery mobile est requis pour que les fonctions startroll et stopscroll fonctionnent.
La fonction anti-rebond est incluse pour atténuer tout décalage créé par l'élément collant.
Testé sous iOS10.
la source
Je viens de sauter par-dessus quelque chose comme ça hier en définissant la hauteur de #a sur la hauteur visible maximale (la hauteur du corps était dans mon cas) lorsque #b est visible
ex:
ps: désolé pour l'exemple tardif, vient de remarquer qu'il était nécessaire.
la source
J'ai eu le problème, ci-dessous les lignes de code l'ont résolu pour moi -
la source