iOS Désactiver le Défilement des pages avec trop-plein-de défilement: appuyez sur
Donc, disons que nous voulons faire une webapp se sentir comme une application native avec "Ajouter à l'Écran d'Accueil." L'une des premières étapes est de désactiver le défilement par défaut. Facile, droit?
//window or document
window.addEventListener("touchmove", function(event) {
//no more scrolling
event.preventDefault();
}, false);
C'est tout beau dans le meilleur des mondes jusqu'à ce que vous ajoutez overflow-scrolling
au mélange. Pour être précis, sur iOS, il serait -webkit-overflow-scrolling: touch
.
/* #scrollable happens to be a ul */
#scrollable {
overflow-y: auto;
-webkit-overflow-scrolling: touch;
}
Par l'ajout de l'événement de la prévention, de l'accélération matérielle pour le défilement dans un conteneur n'a pas de fonction, clairement pas l'effet escompté.
La solution la plus évidente ressemble à quelque chose comme ceci:
//you could do this for multiple elements, of course
var scrollable = document.querySelector("#scrollable");
scrollable.addEventListener("touchmove", function(event) {
//no more bubbling :)
event.stopPropagation();
}, false);
Cette solution présente un problème, cependant, si vous essayez de faire défiler vers la gauche ou la droite dans #scrollable
, il revient à la valeur par défaut de défilement de l'auditeur. Clairement, alors, vous devez surveiller les événements pour voir si le touchmove
événement est suivi de gauche ou de droite, de droite? Malheureusement, non, comme il le fera aussi, en vertu de circonstances, je n'ai pas tout à fait comprendre, revenir à la valeur par défaut de défilement de l'écouteur lorsque vous faites défiler verticalement dans le conteneur.
Maintenant? Pour aggraver les choses, nous, l'idéal serait d'être capable de gérer click
ou cliquez-comme les événements sur l'individu li
s (lire: touchstart
):
var items = scrollable.querySelectorAll("#scrollable li");
for (var item = 0; item < items.length; item++) {
items[item].addEventListener("touchstart", function() {
//handle the touch start
}, false);
}
Pour résoudre ce problème, on pourrait tourner à l'utilisation des click
événements, mais qui est par défaut le but de faire de la webapp "feel" natif en raison du délai entre les écoutes et la réponse. Pour résoudre ce problème, nous allons ajouter un écouteur d'événement pour touchstart
et touchend
:
var items = scrollable.querySelectorAll("#scrollable li");
var activeItem = null, startTouch = null;
for (var item = 0; item < items.length; item++) {
items[item].addEventListener("touchstart", function(event) {
startTouch = event.touches[0];
activeItem = this;
}, false);
items[item].addEventListener("touchend", function(event) {
var touch = event.changedTouches[0];
var deltaX = touch.pageX - startTouch.pageX
var deltaY = touch.pageY - startTouch.pageY;
//require the touchstart to be within 10 pixels of the touchend
if (deltaX * deltaX + deltaY * deltaY <= 100)
//handle "click" event
}, false);
}
Que tout est bel et bon, mais nous n'avons pas encore résolu le problème avec la page par défaut, le défilement de la prise de contrôle de certains touchmove
événements. Des idées?
OriginalL'auteur skeggse | 2013-03-09
Vous devez vous connecter pour publier un commentaire.
Essayez d'échanger autour de la logique dans votre
window
etscrollable
élément auditeurs comme suit:Cette façon, vous n'prévenir par défaut lorsque vous essayez de faire défiler les non-défilement des éléments.
Vous aurez toujours un problème que dans le haut/bas de l'défilement de contenu à partir d'un glisser-peut causer de l'ensemble de l'application de "rebondir". Pour résoudre ce problème, voir Joe Lambert ScrollFix.
OriginalL'auteur rharper