Quindi diciamo che vogliamo fare in modo che una webapp si senta come un'app nativa con "Aggiungi alla schermata Home". Uno dei primi passaggi è disattivare lo scorrimento predefinito. Facile, giusto?iOS Disabilita scorrimento pagina con scorrimento overflow: toccare
// window or document
window.addEventListener("touchmove", function(event) {
// no more scrolling
event.preventDefault();
}, false);
Questo è tutto bene e dandy finché non si aggiunge overflow-scrolling
al mix. Per essere precisi, su iOS sarebbe -webkit-overflow-scrolling: touch
.
/* #scrollable happens to be a ul */
#scrollable {
overflow-y: auto;
-webkit-overflow-scrolling: touch;
}
Aggiungendo prevenzione evento, scorrimento accelerazione hardware in un contenitore non funziona, chiaramente non l'effetto desiderato.
La soluzione più ovvia simile a questa:
// 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);
Questa soluzione presenta un problema, tuttavia, se si tenta di scorrere verso sinistra o destra in #scrollable
, si ritorna a chi ascolta di default di scorrimento. Chiaramente, quindi, dovresti monitorare gli eventi per vedere se l'evento touchmove
si trova a sinistra oa destra, giusto? Purtroppo, no, come sarà anche, in circostanze che non capisco del tutto, ripristinare il listener scroll di default quando si scorre verticalmente nel contenitore.
E adesso? A peggiorare le cose, saremmo idealmente essere in grado di gestire click
o click-come gli eventi sui singoli li
s (leggi: 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);
}
Per risolvere questo problema, potremmo rivolgiamo a semplicemente usando click
eventi, ma quello è l'obiettivo di rendere il webapp "sentirsi" nativo a causa del ritardo tra intercettazione e risposta. Per risolvere questo problema, aggiungeremo un listener di eventi per touchstart
e 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);
}
Questo è tutto bello e buono, ma non abbiamo ancora risolto il problema con la pagina di default scorrimento prendere il controllo di alcuni touchmove
eventi. Qualche idea?