问题描述
所以,让我们想让webapp感觉像一个原生应用程序添加到主屏幕。首先的步骤之一是禁用默认滚动。很容易,对吗?
So let's say we want to make a webapp feel like a native app with "Add to Home Screen." One of the first steps is to disable the default scrolling. Easy, right?
// window or document window.addEventListener("touchmove", function(event) { // no more scrolling event.preventDefault(); }, false);
这是所有罚款和dandy,直到你添加溢出滚动到组合。更确切地说,在iOS上,它将是 -webkit-overflow-scrolling:touch 。
That's all fine and dandy until you add overflow-scrolling to the mix. To be precise, on iOS it would be -webkit-overflow-scrolling: touch.
/* #scrollable happens to be a ul */ #scrollable { overflow-y: auto; -webkit-overflow-scrolling: touch; }
通过添加事件阻止,容器中的硬件加速滚动不起作用,
By adding event prevention, hardware-accelerated scrolling in a container does not function, clearly not the intended effect.
显而易见的解决方案看起来像这样:
The obvious solution looks something like this:
// 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 事件是否向左或向右跟踪,对吗?不幸的是,没有,因为它也将在情况下我不完全明白,当在容器中垂直滚动时,恢复为默认滚动监听器。
This solution introduces a problem, however, if you try to scroll left or right in #scrollable, it reverts back to the default scroll listener. Clearly, then, you should monitor the events to see if the touchmove event is tracking left or right, right? Unfortunately, no, as it will also, under circumstances I don't entirely understand, revert to the default scroll listener when scrolling vertically in the container.
现在什么?更糟糕的是,我们理想地能够处理个人 li 的点击阅读: touchstart ):
Now what? To make matters worse, we would ideally be able to handle click or click-like events on the individual lis (read: 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); }
为了解决这个问题,我们可以简单地使用点击事件,但默认的目标是使webapp感觉原生由于轻敲和响应之间的延迟。为了解决这个问题,我们将为 touchstart 和 touchend 添加事件监听器:
To fix this problem, we could turn to simply using click events, but that defaults the goal of making the webapp "feel" native due to the delay between tapping and response. To solve this, we'll add an event listener for touchstart and 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 事件。任何想法?
That's all fine and good, but we still haven't solved the problem with default page scrolling taking control of some touchmove events. Any ideas?
推荐答案
尝试在窗口 scrollable 元素侦听器如下:
Try swapping around the logic in your window and scrollable element listeners like so:
// 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
您只能在尝试滚动不可滚动元素时阻止默认值。
This way, you only prevent default when trying to scroll non-scrollable elements.
您仍然有一个问题,在可滚动内容的顶部/底部开始拖动可能会导致整个应用程序弹回。要解决此问题,请参阅。
You will still have a problem that at the top/bottom of the scrollable content starting a drag can cause the whole app to "bounce". To fix this problem, see Joe Lambert's ScrollFix.
这篇关于iOS禁用页面滚动与溢出滚动:触摸的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!