はじめに
この記事は「リアズ Advent Calendar 2020」の11日目の記事です。
皆さん初めまして。リアズフロントエンジニアのよしだです。
今年3月に入社して主にフロントエンドエンジニアとして弊社運営の各ライブチャットサイトの
html5対応などサイトの改修を行っています。
人生2度目の転職と新型コロナが重なり今年はあっという間に時が過ぎていきました。
本日はそんなリアズのフロントエンジニアとしての9ヶ月間の勤務の中で、ある不具合とその対応についてお話しします。
目次
iPhone Safariだけソフトキーボードが要素を押し上げてしまう
今年の秋頃、何故かiPhoneのsafariだけチャットの入力フォームを押下してソフトキーボードを起動すると
何故か中途半端に要素が押し上げられ、映像の一部が隠れてしまうという状態になっていました。
文字だけではイメージしづらいので実際のチャット画面の画像で説明します。
発言ボタンを押下すると、写真の様に入力フォームが表示され、ソフトウェアキーボードが出現します。
それと同時に要素が少し上にずれてしまい、実際の配信画面が一部隠れてしまっているのがわかるかと思います。
なお、Androidではこの様な挙動は起きず、要素が上に上がってしまうこともありませんでした。
何故、iPhone Safariだけこの様な挙動になるのか、それはsafariの仕様?から来るものでした。
具体的に公式のドキュメントなどに記載されていたわけではなく、私が動作を確認して見つけたものなので
断定はできませんが参考程度に次の画像を見てください。
次の画像はVueのデモページで、vueのイメージ画像の配下に適当なinputタグを配置し、フォーカスを当てた時の画像になります。
入力フォームが表示領域の上下等間隔の真ん中に位置していることがお分かりでしょうか?
どうやらiPhone Safariではinputなどの入力要素にフォーカスが当たった場合、自動的に対象のフォームが表示領域の中央に位置する様に自動的に動きます。先ほどの入力フォームもこの挙動があったために、動画部分が画面外に一部押し上げられてしまった様に見えたわけですね。
対応方法
実は要素が押し上げられることなく、ソフトキーボードを表示する方法があります。
結論を先に述べると入力フォームを要素の最上部に配置している状態でフォーカスを当てると
表示領域の中央補正がなく、そのままソフトキーボードを表示することができます。
代表的なのはスマホブラウザ版のyahooの検索フォームなどでしょうか。
チャット画面で行うと以下の画像のイメージになります。
しかしこのままではチャットをやるには不格好ですし、使いづらいですね。
そこで、下記の様な実装を行うことにしました。
// ソフトウェアキーボード起動中に一時的に入力フォームを画面最上部に移動し、すぐ元の位置に戻す
// はじめに対象の入力フォームの要素を取得する
const form = document.getElementById('入力フォームのId');
// Vueで実装した入力フォーム要素に設定している表示/非表示のフラグを非表示にする
this.status = 非表示時の値
// bottomプロパティを削除し、topプロパティを付与して一瞬画面上部に移動
form[0].style.removeProperty("bottom");
form[0].style.top = "0";
form[0].style.opacity = "0";
// その後すぐ表示/非表示のフラグを表示に変更して、表示時限定で適用されるcssを反映する
// これにより上記のcssが無効となる
this.status = 表示時の値
// 入力フォームにフォーカスする
focus();
ソフトウェアキーボードが表示されるのがフォーカスメソッドが実行された後になるので意味がないのでは?
と思われるかもしれません。ですがVueの表示/非表示のフラグを変えてVueが更新されるよりも早く
フォーカスメソッドが実行されるので、入力フォームがまだ画面最上部にある状態でフォーカス、
ソフトウェアキーボードが表示される事で要素を押し上げることなくキーボードが表示されるのです。
本来はソフトキーボードが表示中かどうかjavascriptで取れれば良かったのですが、
残念ながらjavascript側からソフトウェアキーボードが起動途中なのか、表示中かを検知するライブラリは存在しません。
一応表示されているかどうかは表示されている要素の大きさを取得すれば判定はできそうです。
これが最適解とは言い切れませんが、同じ現象でお悩みの方の一助になれば幸いです。
その後
今のところは不具合の報告もなく動いています。
ただブラウザのアップデートによっては挙動が変わってしまう場合もあるので注意が必要です。
こうやってQiitaに書いて振り返ってみると結構力技によるゴリ押し感がすごいですね……。
もっとスマートにできる方法があればいずれ直してみたいと思います。
終わりに
2020年12月現在、リアズではサーバーサイドエンジニアを募集しています。
完全リモートもOKなので、興味がある方は是非募集要項に目を通していただければ幸いです。
リアズ経験者採用 サーバーサイドエンジニア