2013-03-09 103 views
9

因此,我們假設我們想讓webapp使用「添加到主屏幕」來使用本機應用程序。第一步是禁用默認滾動。很簡單,對吧?iOS禁用頁面使用溢出滾動進行滾動:touch

// window or document 
window.addEventListener("touchmove", function(event) { 
    // no more scrolling 
    event.preventDefault(); 
}, false); 

,直到您添加overflow-scrolling進來這是所有罰款和花花公子。準確地說,在iOS上它將是-webkit-overflow-scrolling: touch

/* #scrollable happens to be a ul */ 
#scrollable { 
    overflow-y: auto; 
    -webkit-overflow-scrolling: touch; 
} 

通過添加事件預防,硬件加速滾動容器不起作用,顯然不是預期的效果。

顯而易見的解決方案看起來是這樣的:

// 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); 

該解決方案引入了一個問題,但是,如果你試圖向左或向右滾動在#scrollable,它將恢復爲默認的滾動監聽器。很明顯,那麼你應該監視事件,看看事件是跟蹤左邊還是右邊,對吧?不幸的是,在我不完全理解的情況下,不會,當在容器中垂直滾動時,恢復爲默認滾動偵聽器。

現在呢?更糟糕的是,我們從理論上是能夠處理click或點擊類似事件對個人li S(讀: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); 
} 

要解決這個問題,我們可以把簡單地使用click事件,但由於點擊和響應之間的延遲,默認設置使web應用程序「感覺」本機的目標。爲了解決這個問題,我們將添加一個事件偵聽器touchstarttouchend

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); 
} 

這一切優秀和良好,但我們仍然沒有解決的默認頁面滾動服用一些touchmove事件的控制問題。有任何想法嗎?

回答

8

試着在邏輯交換在windowscrollable元素聽衆像這樣:

// 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 

這樣,你只是想滾動的非滾動的元素時,爲防止違約。

您仍然有一個問題,即在可滾動內容的頂部/底部開始拖動可能導致整個應用程序「反彈」。要解決此問題,請參見Joe Lambert's ScrollFix