web-dev-qa-db-ja.com

特定の要素をタッチするときのスクロールを無効にします

図面をスケッチするセクションのあるページがあります。しかし、少なくとも垂直方向のタッチムーブイベントは、モバイルブラウザーで使用するときにページをスクロールします(これにより、スケッチエクスペリエンスが低下します)。 a)ページのスクロールを無効化および再有効化する方法はありますか(したがって、各行の開始時にオフにできますが、各行の終了後にオンに戻すことができます)、またはb)のデフォルトの処理を無効にしますスケッチが描画されるキャンバスに移動するtouchmoveイベント(およびおそらくスクロール)(スケッチはそれらを使用するため、完全に無効にすることはできません)?

違いがある場合は、スケッチにjquery-mobile vmouseハンドラーを使用しました。

更新:iPhoneで、スケッチするキャンバスを選択するか、描画する前に指を少しだけ保持すると、ページがスクロールしません。ページ。

52
Scott Hunter

touch-action CSSプロパティをnoneに設定します。これは passive event listeners でも機能します:

touch-action: none;

このプロパティを要素に適用しても、イベントがthat要素から発生している場合、デフォルト(スクロール)動作はトリガーされません。

57
John Weisz

注:@nevfのコメントで指摘されているように、このソリューションは機能しなくなる可能性があります(少なくともChromeでは) パフォーマンスの変更のため 。推奨事項は、 touch-action を使用することです。これは、@ JohnWeiszの answer でも提案されています。

@Llepwrydの回答と同様に、特定の要素上でスクロールするのを防ぐために、ontouchstartontouchmoveの組み合わせを使用しました。

私のプロジェクトからそのまま撮影:

window.blockMenuHeaderScroll = false;
$(window).on('touchstart', function(e)
{
    if ($(e.target).closest('#mobileMenuHeader').length == 1)
    {
        blockMenuHeaderScroll = true;
    }
});
$(window).on('touchend', function()
{
    blockMenuHeaderScroll = false;
});
$(window).on('touchmove', function(e)
{
    if (blockMenuHeaderScroll)
    {
        e.preventDefault();
    }
});

基本的に、私がやっていることは、jQuery .closestを使用して別の子の要素で開始するかどうかを確認するためにタッチスタートでリッスンし、スクロールを行うことでタッチ動作をオン/オフできるようにすることです。 e.targetは、タッチスタートが始まる要素を指します。

タッチ移動イベントのデフォルトを回避したいが、タッチイベントの最後にこのフラグをクリアする必要もあります。そうしないと、タッチスクロールイベントは機能しません。

これはjQueryなしで実現できますが、私の使用法では、jQueryが既にあり、要素に特定の親があるかどうかを見つけるために何かをコーディングする必要はありませんでした。

Chrome on AndroidおよびiPod Touchで2013-06-18の時点でテスト済み

41
Turnerj

CSSには小さな「ハック」があり、スクロールを無効にすることもできます。

.lock-screen {
    height: 100%;
    overflow: hidden;
    width: 100%;
    position: fixed;
}

そのクラスを本体に追加すると、スクロールが防止されます。

21
Mehdi
document.addEventListener('touchstart', function(e) {e.preventDefault()}, false);
document.addEventListener('touchmove', function(e) {e.preventDefault()}, false);

これによりスクロールが防止されますが、カスタムのイベント処理方法を定義しない限り、他のタッチイベントも中断します。

18
user1720624

最終的な解決策は、overflow: hidden;document.documentElementを設定することです。

/* element is an HTML element You want catch the touch */
element.addEventListener('touchstart', function(e) {
    document.documentElement.style.overflow = 'hidden';
});

document.addEventListener('touchend', function(e) {
    document.documentElement.style.overflow = 'auto';
});

タッチの開始時にoverflow: hiddenを設定することにより、ウィンドウを超えるものはすべて非表示になり、スクロールできるコンテンツがなくなります(スクロールするコンテンツはありません)。

touchendの後に、overflowauto(デフォルト値)に設定することにより、ロックを解放できます。

<html>を使用してスタイリングを行うことができるため、これを<body>に追加することをお勧めします。また、子が予期しない動作をする可能性があります。

編集:touch-action: none;について-Safariはサポートしていません MDNによる

1
soanvig

タッチイベントが発生している間にスクロールしたくないものにオーバーフローを隠してみてください。たとえば、開始時にオーバーフローを非表示に設定し、終了時に自動に戻します。

試しましたか?これがうまくいくかどうか知りたいです。

document.addEventListener('ontouchstart', function(e) {
    document.body.style.overflow = "hidden";
}, false);

document.addEventListener('ontouchmove', function(e) {
    document.body.style.overflow = "auto";
}, false);
0
Woody