iphone iOS safariの「戻る」ボタンの問題

今回はiOS safariブラウザの「戻る」ボタンで画面遷移したときキャッシュを読みに行く事で起こる問題を解決します。

方法は「戻る」ボタンで画面遷移したらjavascriptで強制的にリロードするというものです。

スピード的には当然キャッシュを読みに行った方が早いので、このリロードするという方法を使うと若干遅くはなります。

キャッシュを読みに行く事で起こる問題点

iPhoneまたはiPad用webページの開発をしていると思わぬところでつまづく。

今回のクライアントからの苦情はiphone ios8 safariの戻るボタンの問題。

あるページ(A)のボタンをタップするとプルダウンメニューが出現して、そのメニューをクリックでリンク先ページ(B)へ遷移。

ios_backButton
リンク先ページ(B)からページ(A)に戻りたいのでブラウザsafariの「戻る」ボタンを押すが、戻ってみると前回操作したプルダウンメニューが開きっぱなしになっている。

ios_backButton02
戻ったときはページ(A)の通常の状態(プルダウンメニューは閉じている)になっていないとヨロシクないのだ。

ios_backButton01
いちいちリロードすれば通常の状態には戻るのだが、それでは困る。
さっそく調べてみた。




androidのブラウザの「戻る」ボタンはリロードするが、iPhone ios safariのそれはブラウザに保存されたキャッシュを読みにいく。

そうなんだ、じゃあ、なんのためにios safariはキャッシュを読みにいくのか?

androidブラウザの「戻る」ボタンを押すと再読み込みをする、つまりサーバーにhttpリクエストを実行するので、その分時間がかかってしまう。

一方、ios safariの場合、ブラウザに保存されたキャッシュを読みにいく。
いちいちサーバーにリクエストをしない、つまり再読み込みをしないので、高速なんだね。
その事により「戻る」「進む」ボタンを押して移動するときのスピードがアップするので、ユーザーにとっては快適である。
iphone ios safariはそのためブラウザに保存されたキャッシュを読みにいくわけ。

今回の解決策

ページを離脱するときの状態(プルダウンメニューが開いている)がキャッシュされていて、「戻る」ボタンを押すとその状態が再現されてしまう。

今回の場合、 javascriptでプルダウンメニュー要素が開くようにクラスを生成しているので、その状態がキャッシュされているために起こった現象だ。

リロードしたら初期状態に戻る(クラスは消滅)わけだがら、「戻る」ボタンを押したらリロードするように出来たらいいわけだ。
遷移のスピードが遅くなってしまうがとりあえず今回はこれで対策してみる。

対応策:

これでiPhone iosの戻るボタンでもリロードさせる事が出来る。

onpageshow:ロードの有無に関わらずページが表示された状態。

キャッシュを読みに行ったかどうかはevent.persistedで判断する。
これが true になった場合には、キャッシュされたページを読みこむのでwindow.location.reload()で強制的にリロードする。

他にも色々やり方はあるがとりあえず今回はこれで対応した。

他のiOS関係の記事はこちら

iOSでデータベースを利用する→SwiftData(Swift製SQLiteラッパー)

AppStore申請後に実機にアプリをインストールしようとしたらエラー(A valid provisioning profile for this executable was not found)

エラーメッセージ→(Overriding method with selector ‘touchesEnded:withEvent:’ has incompatible type ‘(NSSet, UIEvent) -> ()’)

ios開発メモ一覧

コメント

  1. りっちゃん より:

    こんにちは!
    拝見させてもらいました!
    まさに今iPhoneのSafari使用中です。
    掲載されておられるコマンド(Window onpageshow〜)は、Safariの中のどこの欄に入力すれば良いのでしょうか⁇
    ぺーぺーですいませんが
    気が向かれましたら教えて下さいませ。。

    • 管理人 より:

      りっちゃん、どうも。管理人です!

      質問されている意味がよくわかりませんでしたが、
      window.onpageshow云々について言うと、これはjavaScriptです。

      Safariのどこかに入力するものではありません。
      javaScriptのファイルとしてサーバーにアップロードしてサイトを表示するときに読み込まれるものです。

      今回のケースでいうとあるサイトを作ってそれをiPhoneのSafariで見て場合に起きる問題に対処するためにwindow.onpageshow云々のプログラムが書かれたjavaScriptファイルを設置すると解決するよ、という話です。

      どうもいい説明が出来ないけど、どうですか、わかります?

      • りっちゃん より:

        こんばんは☆
        こちらに返信があったのですね気付きませんでしたありがとうございます(╹◡╹)
        申し訳ございませんが分かりません…
        とりあえずpcが必要なのでしょうか?
        iPhoneのSafariでブックマークレット作って(URLに管理人様が書いておられたプログラムを丸々コピーして貼り付けてみました)対象ページでブックマークレットをタップしてもURLが開けません!と表示されて進めません。。
        そもそもブックマークレットでは、そのようなプログラム実行は無理なんでしょうか⁇

  2. りっちゃん より:

    連投すいません追記です☆
    iPhoneのSafariで
    下にスクロール
    javascript:window.scrollTo(0,document.documentElement.scrollHeight);

    ↑これをブックマークレット登録して実行してみるとちゃんと機能してるのです(;o;)

    長いプログラム(コード)だから
    ページが開きません、URLが表示できませんという事になったのでしょうか…

    • 管理人 より:

      りっちゃんさん、そーですか、ブックマークレットで使いたかったのですね。
      何年かぶりでちょっとやってみましたよ。

      わたしが記事の中で書いていたコードを一行にするとこんな感じ。
      javascript:window.onpageshow=function(event){if(event.persisted){window.location.reload();}};

      これでブックマークレット登録をしました。
      iPhone6で実行してみると、「URLが開けません」の表示が出て、りっちゃんさんが言ったとおりで「ああこうなるのか」とは思ったのですが、色々試してみたら「URLが開けません」の表示は出なくなりました。
      試したコードは
      javascript:window.onpageshow=function(event){if(event.persisted){window.location.reload();}};alert(“開いたかな?”);

      これを実行するとポップアップウィンドウが開いて「開いたかな?」が表示されます。

      alert(“開いたかな?”);の前のところでエラーになっていたら止まるはずなので、エラーなしで最後までコードが実行されたと思います。

      ただ、ここで実行したコードでは関数を設定しただけなので何も起こりません。

      で、どんな関数を設定したかというと記事の中で書いていたように、「戻る」ボタンなどが押されたような状況で画面遷移が起こったときはリロードをして!という設定をしたのです。
      それじゃ、ここで「戻る」ボタンを押すとどうなるのか?
      設定はリセットされてなくなります。
      ブックマークレットは実行したその瞬間に動作するものなので、今回のような関数を設定するコードなどは無意味なのだと思いますよ。
      間違ってたらごめなさい。