web-dev-qa-db-ja.com

iOSで「touchmove」がウィンドウをスクロールするのを防ぐことはできません

ウィンドウ自体がスクロールしないようにしながら、iOS Webアプリの要素をスクロールしようとしています。ウィンドウでtouchmoveイベントをキャプチャし、プログラムで要素をスクロールし、イベントでpreventDefaultを呼び出してウィンドウ自体がスクロールしないようにします。

残念ながら、これはMobile Safariでは機能しません。ウィンドウは要素の下をスクロールし続けます。この問題は https://bugs.webkit.org/show_bug.cgi?id=163207 で説明されているWebkitのバグとまったく同じように聞こえますが、その問題はiOS 10.3では修正されたはずですが、11.3を実行しています。

touchforcestartをキャッチしてpreventDefaultを呼び出すと、ウィンドウのスクロールが妨げられるように見えますが、touchstartで呼び出しています。ウィンドウはまだスクロールするため、「遅すぎる」ようです。スクロールは、次回touchstartが呼び出されたときにのみ防止されます。

何が起こっているかについてのアイデアはありますか?これは明らかにバグであるため困惑していますが、しばらく前に修正されたようです。

24
Matthew Gertner

私は最近、この同じ問題に遭遇しました。 touchmoveイベントリスナーを登録するときに、{ passive: false }を渡す必要があります。例えば.

document.addEventListener('touchmove', function(e) {
    e.preventDefault();
}, { passive: false });

これは、iOS 11.3にバンドルされているSafari 11.1では、ドキュメントタッチイベントリスナーがデフォルトでパッシブになったためです。この変更は、Safari 11.1で文書化されています リリースノート

Web API

  • [...]
  • ルートドキュメントタッチイベントリスナーを更新して、パッシブモードを使用し、スクロールのパフォーマンスを向上させ、クラッシュを減らしました。
60
user9576791

preventDefaultを2つのイベントにバインドする必要があります:touchmoveおよびtouchforcechange.

document.addEventListener('touchmove', this.preventDefault, {passive: false});
document.addEventListener('touchforcechange', this.preventDefault, {passive: false});

タッチスタートの前にバインドする必要があります

touchstartまたはdragStartハンドラー内でバインドすると、次のドラッグでのスクロールのみを防ぐことができます。

2
User007