2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【バグ?】safariの罠 input type="file" required でバリデーションエラーが画面外で発生した場合、フォーカスだけ当たってスクロールしない

Last updated at Posted at 2023-09-01

2023/09/04 12:00
Typoしていたため、修正版が動作していませんでした。(対応済)

まだまだあったよこんなバグ

先日、こちらの記事を書いたが、

これのデバッグをしている際に、iOS safariだけに起こるバグを見つけてしまった。
というか、見つけてもらった。

それがこれ

※Mac safariは持っていないので未検証

なにこれ・・・?

Edge、Firefox、Android Chromeではもちろんこんなの発生しない。
(Android Firefoxはそもそもsubmitのバリデーションエラーではフォーカスすらしてくれない)

もうどうしようもないので、Javascriptで強引に解決した。

押さえておく前提条件

  1. バリデーションエラーでfocusは当たる
  2. エラーヒントは出ている
  3. でも、スクロールしない
  4. iOS safari以外は問題ない

上記を踏まえた仕様設計

  • focusでイベントを発火
  • 画面内に要素が見えていたらキャンセル(普通にtabキーやクリックでも発火してしまうため)

できた Javascript

修正内容がこちら
たった数行のために、結構時間がかかった。

<script>
  // inputにfocusが当たったのに、スクロールしない場合に強制的にスクロールさせる
  const input = document.querySelector('#file-upload');
  input.addEventListener('focus', () => {
    // 発火したときに画面外だった場合、画面内にスクロールする
    // 少し遅らせないと、エラーヒントが表示されない
    setTimeout(() => {
      const rect = input.getBoundingClientRect()
      if (rect.top < 0 || rect.bottom > window.innerHeight) {
        input.scrollIntoView()
      }
    }, 100)
  });
</script>

ひっかかったポイントが、イベント発火とスクロールを同時に起こすとヒントが出ない ということ。
また、スクロールが起こるブラウザも同時発火だとスクロール前の座標を取得してしまう ので、setTimeoutでケアしてあげる必要がある。

なお、スクロール位置が遠い場合、0.1秒では間に合わないかもしれないので、適宜修正が必要

まとめ

画像アップロードや個人情報を扱う系のWebサイトは一度見直した方がいいと思う。

少なくとも 2023/9/1現在の最新バージョン iOS 16.6 ではバグが発生するので、はやく直してほしい。

っていうか、Android Firefox フォーム系やばいけど、どうなってんの?

2
0
2

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
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?