所以我们可以说,我们想使web应用程序的感觉像一个原生应用“添加到主屏幕。” 其中的第一个步骤是禁用默认滚动。 很简单吧?
// 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
,它将恢复为默认的滚动监听器。 很明显,那么,你应该监视事件,以查看是否touchmove
正在跟踪向左或向右的事件,对吧? 不幸的是,没有,因为它会还,根据情况,我并不完全了解,在容器中垂直滚动的时候恢复到默认的滚动监听器。
怎么办? 更糟糕的是,我们从理论上是能够处理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应用程序的“感觉”原生因窃听和反应之间的延迟的目标。 为了解决这个问题,我们将添加一个事件侦听器touchstart
和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);
}
这是一切优秀和良好的,但我们仍然没有解决的默认页面滚动服用一些控制问题touchmove
事件。 有任何想法吗?