2013-03-09 17 views
9

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?

risposta

8

provare a scambiare intorno alla logica nei window e scrollable ascoltatori elemento in questo modo:

// window or document 
window.addEventListener("touchmove", function(event) { 
    if (!event.target.classList.contains('scrollable')) { 
    // no more scrolling 
    event.preventDefault(); 
    } 
}, false); 

// No special listeners needed on .scrollable elements 

In questo modo, si evita solo di default quando si cerca di scorrere elementi non scorrevoli.

Avrai ancora un problema che nella parte superiore/inferiore del contenuto scorrevole che inizia un trascinamento può far "rimbalzare" l'intera app. Per risolvere questo problema, vedere Joe Lambert's ScrollFix.

Problemi correlati