Help us understand the problem. What is going on with this article?

Android Chrome beta (v.56) でdocumentに対するtouchイベントのpreventDefaultが効かない

More than 3 years have passed since last update.

 注意

この記事はAndroid版Google Chrome beta(56.0.2924.23)を元に記述しています。
betaなので今後のChromeのアップデートで挙動が変わる可能性があります。

三行でおk

  • パフォーマンスのため window とか document に対する touchXXX は、preventDefaultが無効になる
  • addEventListener 時に明示的に {passive: false} を指定すればOK
  • いも

どういうわけか

document.addEventListener('touchstart', function (e) {
  e.preventDefault();

  // 以下、楽しい処理
});

みたいなコードを書くと、画面をスクロールできないようになります。
ゲームなど、画面まるごと <canvas> みたいなときにはスクロールされても困るので、
こういうことをよくやったりしますね。1

が、 Android Chrome beta (56) で、思ったように動かなくなりました。

Chrome(55)ではスワイプしても大丈夫だったものが、
Chrome beta(56)ではキャンセルされず、
ブラウザのリロードアクションが発火している様子です。
つらみ。

原因

コンソールに以下のようなwarningが表示されています。

Unable to preventDefault inside passive event listener due to target being treated as passive. See https://www.chromestatus.com/features/5093566007214080

つまり、どゆこと?

上のサイトに詳しく説明がされているのですが、
addEventListener のコールバック内で
 preventDefault が呼ばれるか確認してからじゃないと、
 画面をスクロールしていいのかわからない!」
というのがパフォーマンス上の問題になっており、
preventDefault を確認しない(= preventDefault が呼ばれないものとする)オプションが
addEventListener に追加されたそうです。

// preventDefaultを呼ばないのでスクロールをキャンセルしないのだけど、
// 実際に処理を実行しないとそれがわからないため、スクロールが遅延する
document.addEventListener('touchstart', function (e) {
  同期的でめっちゃ重すぎる処理();
});

// 第三引数のオプションに passive: true を渡すと、
// 中に preventDefault が存在しない扱いになる(=呼んでも意味ない)ので、
// 処理を実行せずにスクロールを開始できる
document.addEventListener('touchstart', function (e) {
  同期的でめっちゃ重すぎる処理();
}, { passive: true });

passive のデフォルト値は false なのですが、Google先生いわく
「そもそも root 要素みたいなもので preventDefault 使うこと普通ないよな?
 快適なインターネットのためにデフォルトで passivetrue にするぞ!」
とのことらしいです。

確かにページをスクロールさせたくない、っていう需要は普通はない。
僕はゲームだからある……(◞‸◟)

どうしたらいいのか

  • まずホントに document などで preventDefault する必要があるか考える
    • スクロールが遅延するのは事実
  • 必要なのであれば第三引数に {passive: false} を明示的に渡す

そもそも beta での挙動なので変わるかもですが、
対応が必要な方は頑張ってください。


  1. Android Chromeの場合、上から下にスワイプするとリロードかかっちゃうのでゲームが死ぬ 

ru_shalm
Ruたん(るたん)です。RubyとJavaScriptを書いたり、Webサービスの企画をしているよ。 個人の活動ではブラウザゲームをつくっています。
http://rutan.info
dwango
Born in the net, Connected by the net.
https://dwango.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away