2020-11-10に更新

【Apache Laravel Vue.js Vuetify】webアプリをスマホに対応させるためにやったこと

Apache+Laravel+Vue.js+Vuetify で作った社内ツールをスマホ対応したときに行った作業内容メモ。
ほんとにiosが嫌いになりそうだった

対応ブラウザは、

  • chrome(PC, Android, ios)
  • safari(ios)

まずはiPhone、Androidのデバッグが出来るように準備する

それぞれの端末を持っていれば、PCに繋いでデバッグができる!なんて素晴らしい。
iosはiPhone以外にもiPad、iPod touch でも問題なし。
それぞれ以下を参考に。

Android:https://qiita.com/hojishi/items/12b726f8b02ef3d713e4
ios:https://webkatu.com/archives/ios-safari-debug-on-windows/

Polyfillを入れる

Vuetifyの公式ドキュメントに則って入れればOK。

npm install babel-polyfill --save
npm install @babel/preset-env --save

インストール後、
import Vue from 'vue' とか
import vuetify from '@/plugins/vuetify
を書いているファイルに、
import 'babel-polyfill' を追加。
(自分の場合は /resources/assets/js/app.js

ルートディレクトリの .babelrcに、

 {
  "presets": ["@babel/preset-env"]
}

対応していないjsを地道に直す

特に問題なければ、↑を行えば画面は表示されるはず…と思っていたのだが、画面が真っ白だった。

エラーを調べると、どうやら正規表現で後読みを使っているのが原因みたいだったので、該当箇所を修正。
(safariは後読みに対応していない)

※書いている最中に気づいたけど、それってつまりうまくPolyfillが使えていなかったのでは…??

「Error: Network Error POST 応答を解析できません」を直す

iosのみ起きる謎現象。これに2日かかった…
自分は、Apacheの設定を変更で直った。

<Directory "/var/www/html/public">
    AllowOverride All
    # Allow open access:
    Header unset Upgrade       ←これを追加
</Directory>

とりあえずここまでで画面が開けるようになりました。
以降は細かい部分です。

スクロールを入れたくないのにスマホだと入ってしまう

webアプリ全体にスクロールを入れたくない場合、bodyにheight:100%とか入れればPCでは大丈夫だったりしたんですが、
スマホだとどうにも謎のスクロールが入ってしまうので、以下のように対応。

<html id="content">
 …

※jsでhtmlのところにstyleを指定する方法がわからなかったのでid属性を無理やり、、、

const windowHeight = window.innerHeight;   // windowの高さを取得

// <html>の高さを、windowsの高さいっぱいに設定
document.getElementById("content").style.height = windowHeight + "px";
// bodyはheight:100%
document.body.style.height = "100%";

// スクロールバー非表示
// スマホのときはbodyに、PCのときはhtmlにかけないと反映されないっぽいので分ける

const isSP = /iPhone|iPod|iPad|Android/i.test(navigator.userAgent);     
if (isSP) {             
    document.body.style.overflowY = "hidden";
} else {
    document.getElementById("content").style.overflowY = "hidden";
}

…無理矢理感半端ないけど、ひとまずこれでPCでもスマホでも画面いっぱいでコンテンツが収まるようになった。

iosだけ、キーボードのenterでボタンクリック判定されてしまう

PCやAndroidでは大丈夫なのに、iosだけ起きる謎現象。
改行する度にボタンが押されて送信されるという、、、、

※単純にv-formのsubmitイベントが発火してしまっている場合は、こちらを参考に。

根本的な原因はわからなかったため、
入力文字が空欄・改行のみの場合は、ボタンクリックで呼ばれる処理が走らないようにした。

<textarea v-model="inputText"></textarea>
<v-btn @click="submit()">送信</v-btn>

data: () => ({ inputText: "", }), computed: { /** * 空文字判定 */ isTextEmpty() { return !this.inputText || !this.inputText.match(/\S/g); }, }, methods: { submit() { if (this.isTextEmpty) return; // 以下送信処理 } }

iosだけファイルアップロードができない

ファイル選択のダイアルボックスを開く→ファイルを選択→アップロード
という流れのとき、iosだけダイアルボックスが開かないという謎現象。
エラーも出ない…

調べてみたら、どうやらinput.onchangeが動いていないようだった。

function uplod() {
    return new Promise(resolve => {
        const input = document.createElement('input');
        input.type = "file";
        input.multiple = false;
        input.accept = "image/gif,image/jpeg,image/png";
        input.onchange = event => {
            var file = event.target.files[0];
                resolve(file);                    
            };
            input.click();
        });
}

ios以外は↑でも動いたが、どうやらiosではちゃんと<input>要素をDOMに追加してあげないといけないらしい。
参考:https://stackoverflow.com/questions/47664777/javascript-file-input-onchange-not-working-ios-safari-only

というわけで、以下のように修正

function uplod() {
    return new Promise(resolve => {
        const input = document.createElement('input');
        input.type = 'file';
        input.multiple = false;
        input.accept = "image/gif,image/jpeg,image/png";
        document.body.appendChild(input);     // ←DOMに追加
        input.onchange = event => {
            var file = event.target.files[0];
            document.body.removeChild(input);     // ←DOMから削除
            resolve(file);
        };
        input.click();
    });
}

iosだけ画像が縦に伸びる時

これは別記事にもメモしてあるが、
display:flex;を指定している箇所に、align-items: flex-start;を追記するだけ。
参考:https://nichiyogogo.com/image-looks-stretched/

iosだけ、heightを指定した要素内の「overflow-y: visible scroll;」が効かない

これもiosの一部で起きる現象。
safariのバージョンの問題かもしれない。

ますはここを参考に修正。
自分はこのときにも頑なにoverflow-y: visible scrolと書き続けていたら直らず、
素直に overflow-y:auto; にするだけで解決…。

おわり

ほとんどios対応ですね。
Androidはグリッドをちゃんと設定して、表示崩れしないようにだけしてあげれば殆ど動きました。
マジでiosとsafariが嫌いになりそうだった…。

ツイッターでシェア
みんなに共有、忘れないようにメモ

みみみみみ

1歳と7ヶ月くらいの赤ちゃんです。

Crieitは誰でも投稿できるサービスです。 是非記事の投稿をお願いします。どんな軽い内容でも投稿できます。

また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!

有料記事を販売できるようになりました!

こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください。
ボードとは?

コメント