「ホーム画面に追加」を使用して、Web アプリをネイティブ アプリのように感じさせたいとしましょう。最初の手順の 1 つは、デフォルトのスクロールを無効にすることです。簡単ですよね?
// 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 (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);
}
この問題を解決するために、単純に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
これで問題ありませんが、デフォルトのページ スクロールが一部のイベントを制御するという問題はまだ解決していません。何か案は?