2013-03-09 100 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