背景
リリースに向けて実装した画面を動作確認していたところ、他のテスト者から**「Internet Explorer (IE)で、ボタンが押せないよ」**という報告が...!(ピンチ)
いかんせん、普段はChromeを推奨環境してご案内し、プロダクト開発しておりまして、IEに関しては知見も経験も少ない私です。
「さすがにボタンが押せないのはマズイ!対応せねば」と調べた内容を共有します!
どんな仕様を実現しようとしていたか?
- ボタンA (
viewButtonA
)をクリックすると、Msgが発行され、Modelを書き換えることで新たに画面を表示する。 - ボタンAは特定の条件下で表示し、それ以外の場合は何も表示しないという画面を表示する。
具体的なコードの例
OldButton.elm
type Msg
= ClickedButton
viewButtonA : Bool -> Html Msg
viewButtonA isShown =
if isShown then
Html.button [onClick ClickedButton][Html.text "Click Me"]
else
Html.text ""
どんなエラーが発生していたのか?
- ボタンが押せない。押すと以下のようなエラーメッセージがコンソールに表示される。
TypeError:未定義またはNULL参照のプロパティ"j"は取得できません
(TypeError:Unable to get property 'j' of undefined or null reference)
- ボタンが押せないので、Msgも発行されていないため、表示が変わらない。
なぜ起こるか?
-
「何も表示しない」という実装に
text ""
を使用しているため!- ※ただし、必ず起きるというものではなく、
text ""
の描画が、Dom構造の上層に近かったりすると生じることがあるみたいです。
- ※ただし、必ず起きるというものではなく、
- Virtual Domの既知のバグで、こちらにもissueが存在しています。
対策
- 何も表示しない画面を、
div [] []
またはspan [] []
で表現する。 - (特にチーム開発においては)実装者に依存し、予期せぬバグを生むため、関数として切り出し、各モジュールから利用する。
以下がサンプルのコードです。
BlankView.elm
module BlankView exposing (viewBlank)
viewBlank : Html msg
viewBlank =
-- ここは`span [] []`でもバグを回避できます。
div [] []
NewButton.elm
import BlankView exposing (viewBlank)
type Msg
= ClickedButton
viewButtonA : Bool -> Html Msg
viewButtonA isShown =
if isShown then
Html.button [onClick ClickedButton][Html.text "Click Me"]
else
viewBlank
感想
- このバグについては日本語のリソースがほとんどなかったため、Qiitaを書くことに決めました。
- 指定の条件下で何も表示しない、という仕様は結構あるので同じバグに出会ったときに役立つといいなと思ってます。
- 実はチーム内でも過去に同じようなバグを対処したことがあるみたいだったので、改めてルールや方針等の共有はとても大切です!