37
20

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Posted at

## 注意

この記事は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の場合、上から下にスワイプするとリロードかかっちゃうのでゲームが死ぬ

37
20
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
37
20

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?