こんにちわ、PHPエンジニアのエンジニア婦人(@naho_osada)です。
PHPエンジニアとして9年~の経験があります。
ウェブページを作っていると、端末やOSバージョンによって動いたり動かなかったりする事案がよくあります。
ちょっと前まではIE8ガーIE11ガーなんてよくぐちぐちしていましたが、最近はそれは減りました。それでもたまにあります。Edgeで動くんだけど、IE11だとダメとか。さすがにIE8はもう対応しなくなった。
一昔前のフィーチャーフォンのときはさぞ大変な労力だったろうとお察しします。その頃はまだ学生だ。
本日は端末によるもの、iPadだけなんか誤動作してるんだけどどうして?というのが持ち込まれたので、その原因調査と解決をした話です。
問題
アコーディオンメニューありますよね。クリックするとばっと開いて、クリックするとばっと閉じるもの。スマホサイトの上にあるある、PCサイト(あまり)ないない … ①
PCで見ているとさほど必要ではないのですが、スマホだとグローバルナビ(上部のメイン帯のこと)でよく対応します。小さい画面でそんなもん見えてても邪魔だし操作し辛いからね。
それで、「画面領域(幅と高さ)を変えたときにスマホ表示とPC表示に切り替える」っていうjs対応もセットでやることが多いです。 … ②
これはPC画面でブラウザ表示領域を減らしていって、設定した幅でスマホ表示と切り替わるか、で動作確認します。
表示したときの画面幅で判定して、そのあと画面幅を変えてもスマホ表示とPC表示切り替えないっていうことも多いのです。その方がエコだとは思います。大体普通に見ている人はわざわざ画面幅頻繁に変えないだろうし。
本来、これは問題なく実装できるんですが、この度めでたくiPad(Safari)だけ
「スクロールするとボタン押してないのにアコーディオン開く」
現象が起きました。
思考経過
以下、原因追及のためのステップをメモ。
クリックイベントが誤動作しているのか?
調べたところ、そういうわけではありませんでした。
スクロールとクリックがiPadだと同一視されている?
そんな風にも感じず。それだったら他のスマホ端末でも起こりそうなものなのに(その他スマホ端末では起こらなかった)
iPadの仕様?
端的に言えば正解でした。
原因
iPad(Safari)は、ブラウザを下方スクロールするときに、トップのアドレスバー部分が小さくなります。
これが上の②の処理、「ブラウザ画面領域が変わったからメニューを開く」を呼んでしまっていました。window.resize呼んでいたわけ。
jsとしては全く問題がなく、正しく動作していたのですが、こちらの書き方がまずかったんですね。
対処
以下の処理に変更しました。
- 表示したときに画面幅を取得しておき、resizeが働いたときに現在の画面幅を記録する。
- 現在の画面幅と表示したときの画面幅を比較し、幅が変わっていたらメニューを表示して画面幅を再取得する。変わっていない場合は何もしない。
以前よりもこっちのほうがよりエコ運転ですね。
iPad(Safari)の仕様だったので、他の端末では起こらなかったんですね。スクロールしてアドレスバー小さくなるとかないし、PCも。
これでiPadでもアコーディオンメニューが勝手に開くことはなくなりました。