ハトネコエ Web がくしゅうちょう

プログラミングやサーバー・Web制作、チームマネジメントなど得た技術のまとめ

Materialize は iOS 13 以降でのバグがあるので注意!

React や Vue を使っていないサイトにおいて、
Materialize というCSSフレームワークは、
コンポーネントが充分に用意されていて、マテリアルデザインなサイトを製作する上でとても有用です。

Google が開発しているのにコンポーネントが不足したまま開発が放置されてしまった material-design-lite よりはよっぽど……。
マテリアルデザインを提唱してる大元なのだからがんばってほしかった・・・)

一方で、Materialize も 2018年9月に v1.0.0 を出して以降はリリースが止まってしまったのでバグがあります。
iOS 13 以降で発生するバグです。

iOS 13 でのバグとその原因

実際に見てもらうのが早いので動画にしました。

www.youtube.com

このように、押した位置と選択結果が一致しないことが多々あります。
動画は iOS 14 を公式 Simulator で動かしたもので、iOS 14 でも引き続きこのバグが起こることを確認できました。

なぜ起こるかと言うと、このフォーラムで書かれているように、どうやら
touchstart, touchend, そこから 0.2〜0.3 秒ほどおいて mousedown, click といった順にイベントが発火しているようです。

これにより、押された瞬間に dropdown.js は touchend イベントで反応するので閉じるアニメーションを開始するのですが、
押された箇所がどの要素か判定する _handleOptionClick メソッドは、
その名の通り click イベントによって発火するので、アニメーションが開始してから遅れて判定が走ります。

結果として、ドロップダウンが少し閉じている状態でのユーザーのタップ位置の li 要素が選ばれるので、
少し下の要素が選ばれてしまうのです。もしくは何も選ばれないのです。

作者の対応

これに対し、作者はこのコミットで、
ドロップダウンが閉じ始めるタイミングを要素が選択されたあとにすることで対応しています。
(_selectOption メソッドの最後で this.dropdown.close(); しているのがポイント)

残念ながらこの2019年9月の修正は v1.0.1 としてリリースされればよかったのですが、今のところリリースされていないので、
自らコンパイルして JS ファイルを作らない限りはこの修正の恩恵を受けられません。

また、ドロップダウンも同様の問題を抱えているのですが、その修正はされていません。
ドロップダウンメニューのリンクを踏んだら別のページに飛ばされるのですから、ユーザー体験はかなり悪いですね……。

どう対処するか

select について

3通り考えられます。
現在の https://github.com/Dogfalo/materialize の r1-dev の最新コミットから grunt を用いて JS を生成し、それを使う方法。
または、こちらの記事で紹介されているように、最新コミットから select.js だけを取ってきて materialize.js の後で読み込む方法です。
後者の方法はメソッドの上書きをすることでギリ動いているのではと思うので、materialize.min.js でなく materialize.js を使わないと上手くいかない気がします。

3つ目の方法は次で説明します。

dropdown について

この記事で書かれている方法がおもしろかったです。
touchend イベントを付与してしまってそちらに処理してしまう方法です。
元々の click イベントと二重に発生する可能性を持っていますがページ移動処理なのでそんなに困らないという、力技の解決方法でけっこう好きです。

他の解決方法としては、dropdown のオプションである closeOnClick を false に設定することで、
ドロップダウンメニュー内を選んだときに閉じるアニメーションが発生しなくなるので、
誤った箇所が選択されることが無くなります。

このオプションは select においても dropdownOptions というオプションから設定できます。select の問題の対処法の3つ目はこれを用いる方法です。
ただ、領域外を押すまでドロップダウンが閉じてくれないので、select で使うのはユーザー体験としては悪いでしょうね……。

最近の Materialize の動き

最近は Materialize に大きな動きがありました。

なかなか動きを見せない作者に業を煮やし、DanielRuf さんが新しいリポジトリを作成しました。

作成した5月からはしばらく動きを見せていませんでしたが、
(作者から「新しいコミュニティを作るのもなんだから、ここのリポジトリを手伝ってくれる人を募集するよ!」って声をかけられたからだと思う。その後 DanielRuf さんが「ぜひ」と返したあとで作者からの返信が無くなるんだけど……)
7月から活発に動くようになり、コミットが少しずつ重ねられています。

まだ最初のリリースも作られていないので自分でコンパイルしない限りは使えませんが、
上手く行けば、select バグなどが解消された v1.0.1 がリリースされる日が来るかも知れません。

正直、今のところは Material Design for Bootstrap を選択するほうが安全策と言えるのですが、
ボタンのデザインなど Materialize の方がデザインはカッコいいと思うので、今後の動きに注目です。

追記:メンバーになりました

「dropdown のバグを直すために少しいじってみるか〜」と、このブログを書いたあとでさわってみたら
いろいろ問題を見つけてしまい、プルリクエストをいくつか出してコントリビュートしていたところ、
翌日メンバーに招待されました。

英語苦手だけどレビューがんばらなくちゃな〜と思いました。