無趣味の戯言

📄

Safariの仕様に悩まされた備忘録

こんにちは、だいちゃんです。

Web制作者の悩みのタネだった InternetExplorer の公式サポートが終了してからしばらく経ちましたが、未だにクライアントさんからは対応を依頼されてしまう悲しい現状があります。とはいえ、公式のサポートは終了している旨をお伝えすると妥協してくださる案件が増えてきたのも事実です。(もちろん最低限は見れるようにはしてますが...)

そんな中、次なるネックが身近にいました。

そう、Safariです。

最近までデフォルトブラウザを変更出来なかったこともあり、iPhoneユーザーの多くはSafariを愛用しているのではないでしょうか?ましてや、日本ではiPhoneのシェアが恐ろしく高いですからね。切り捨てることは到底できません。

AppleのDNAを100%受け継いでいるため、 ユーザーにとってみては親切で扱いやすいブラウザ かもしれませんが、 Webクリエイター側にはいくつか落とし穴があって制作がしづらいブラウザの1つ です...。IEの場合はレガシーを引き継がなければならないツラさがあって、Safariにはユーザーにトコトン寄り添った結果だと思うので、どちらも悪者扱いは出来ませんが。

最近もSafariでハマりポイントがあったので、回避方法も含めて備忘録として記事にしておこうと思います。

「戻る」のキャッシュ強すぎ問題

恐らくユーザビリティの観点からこういう仕様になっていると思うのですが、「戻る」(ブラウザバック)時にかなり強力なキャッシュが効いている印象です。Chromeなどではページ自体はリロードしつつ、画像など重たいファイルに対してキャッシュを効かせているイメージですが、Safariの場合、ほぼ1ページ全てキャッシュから(DOMの再構築もせず?)表示されているような挙動に見えました。

この場合困るのが、フォームが含まれるページです。

厳密には、フォームの動作によってclass付与によって動作を付けているページです。戻ってきた際に、フォームの入力値が残っているにも関わらず、classは付与されたままなので、ちぐはぐな状態になってしまいます。また、フォーム自体も、既に入力値されているものを再度選択出来なかったりと不安定な動きになってしましました。

対処法としては、ページが表示された時に、キャッシュを読みに行ったかどうかを調べて、 キャッシュを読みに行ってたらリロードさせるという力技。

window.onpageshow = function(event) {
    if (event.persisted) {
         window.location.reload();
     }
};

window.open() ブロックされる問題

これもユーザー的に意図しない動作を抑制する為の仕様なので、 悪意じゃないのがまた歯がゆいところ。

Javascriptで「新しいタブで開く」を実装する際、 window.open(url) を使うと思うのですが、間になにかしらの処理を挟むとSafariの場合ブロックされてしまうようです。ブロックされる時には null が返ってくるという仕様を利用して、下記のようなスクリプトで対策しました。

if(!window.open(url)) {
  location.href = url;
} else {
  window.open(url);
}

ポップアップブロックされてしまった場合、同一タブ遷移になってしまうのが悲しいところです。 onclick属性 として指定すれば動くようだったので、出来れば前処理は別のタイミングで終えておけるようにしておくのがベストですね。処理上それが難しければ、諦めて同一タブ遷移で我慢しましょう。


ブラウザ間の仕様差は、ユーザーとしては自分の肌馴染みの良いものを選べるというメリットがあり重要ですが、制作者にとってはデバック対象が増えるツラさがあります(涙)

もっとも、経験を重ねていけば、ある程度 事前に嫌な予感がするようになる ので、フロー自体で回避可能になったり、差異の少なくなるような書き方が出来るようになってくると思うので、文句を言わずに対応し続けるしかないですね。

参考サイト

Buy Me A Coffee