J'ai quelques problèmes avec une div à défilement sur iOS. Lorsque vous essayez de faire défiler en touchant en dehors d’une entrée, vous faites défiler sans problème, mais lorsque j’essaie de faire défiler et que je touche une entrée, le défilement commence (il y a beaucoup de chances que cela se produise car c’est une div avec beaucoup d’entrées ) il fait défiler la fenêtre entière au lieu de faire défiler la div. Je n'ai pas ce problème dans le bureau ou Android. J'ai trouvé une question similaire ( La balise d'entrée HTML iOS arrête le défilement dans l'élément défilable ) mais il n'a pas non plus de réponse. Bien que je ne trouve pas de bonne solution, j'ai décidé d'empêcher l'événement touchmove
lorsque l'utilisateur touche une entrée, mais ce n'est pas exactement ce que je veux.
Peut-être que quelqu'un a déjà fait face à ce problème et peut aider. Je l'apprécierais vraiment, merci d'avance.
Pour obtenir un défilement dynamique sur iOS 5+, vous avez besoin des éléments suivants:
div {
overflow: scroll;
-webkit-overflow-scrolling: touch;
}
Source: Débordement
Peut-être avez-vous aussi besoin de:
div > * {
-webkit-transform: translateZ(0px);
}
Source: Question similaire dans Stack Overflow
Source 2: Une autre question similaire
Cela m'a rendu fou aussi, après avoir tout testé, j'ai trouvé la réponse suivante de Thomas Bachem ici qui fonctionnait et je l'ai simplifiée.
Ajoutez simplement une classe scrollFix
aux entrées et vous êtes prêt à commencer. (ou appliquer directement que js à n'importe quelle entrée/textarea using$('input, textarea')
Désormais, lorsque vous touchez et faites défiler une entrée sur iOS 8+, tous ses "événements de pointeur" sont désactivés (y compris le comportement problématique). Ces "événements de pointeur" sont activés lorsque nous détectons une simple pression.
$('.scrollFix').css("pointer-events","none");
$('body').on('touchstart', function(e) {
$('.scrollFix').css("pointer-events","auto");
});
$('body').on('touchmove', function(e) {
$('.scrollFix').css("pointer-events","none");
});
$('body').on('touchend', function(e) {
setTimeout(function() {
$('.scrollFix').css("pointer-events", "none");
},0);
});
html {
overflow: scroll;
-webkit-overflow-scrolling: touch;
}
Solution palliative, mais ce faisant, j'ai pu faire fonctionner le défilement même sur les entrées de formulaire. Le JS force un refoulement dans le moteur de rendu, qui est à l'origine du bogue dans iOS8 Safari. Le fait de changer la hauteur en mode automatique améliorait également le défilement lorsque focus sur un élément de formulaire, car le défilement est forcé par le navigateur lors de la focalisation.
Balisage:
<div class="modal-backdrop-container">
<div class="modal-backdrop">
<div class="modal> <!-- Content --> </div>
</div>
</div>
CSS:
.modal-backdrop-container {
z-index: 10;
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
height: 100%;
}
.modal-backdrop {
z-index: 10;
height: 100%;
background-color: rgba(255,255,255,0.5);
overflow: auto;
overflow-x: hidden;
overflow-y: scroll;
-webkit-overflow-scrolling: touch;
}
.modal {
position: relative;
width: 400px;
max-width: 100%;
margin: auto;
background-color: white;
}
JS:
// reflow when changing input focus
$modalInputs = $('.modal').find(':input');
modalInputs.on('focus', function() {
var offsetHeight = modal.$backdrop[0].offsetHeight;
modal.$backdropContainer.css({
'height': 'auto'
});
});
modalInputs.on('blur', function() {
var offsetHeight = modal.$backdrop[0].offsetHeight;
modal.$backdropContainer.css({
'height': ''
});
});
Pas sûr de la ligne var offsetHeight = modal.$backdrop[0].offsetHeight;
est nécessaire, car cela et la modification de la valeur de hauteur devraient forcer une refusion.