wp_is_mobileの判定や、新旧iPadの挙動など

ワードプレス

最近のiPadでは「SafariとChromeで表示がいろいろ変わっちゃう」というところから始まり、改めて確認したり、実機を数種試してみたところでメモ。

wp_is_mobileの中身

元々どういう目的で作られたものかは知りませんが、中身は

  1. ブラウザ情報を覗いて
  2. あらかじめ設定された文字列が含まれていたら
  3. 文字列ごとに条件分岐して
  4. 真偽を返す

というだけのもの。

「is_mobile」も中身は大体同じと思います。

wp_is_mobileやuser agentなどを色々なデバイスで見てみる

現在、ブラウザ右に貼り付いている青いヤツで確認。

 

厄介なのが最近のiPadのSafari。(調べたのは第4世代iPad Air、OS 15.2~)

mobile判定、user agent、デバイス情報がくっちゃくちゃな感じ。

  • デフォルト(環境設定(Safari)「デスクトップ用Webサイトを表示」オン
    wp_is_mobile:false、またuser agentにiPadを含まない
  • 環境設定(Safari)「デスクトップ用Webサイトを表示」オフ
    wp_is_mobile:true、またuser agentにiPadを含む

 

無理矢理まとめると、

  • 基本的にはタッチデバイスであり大画面でもある。
  • wp_is_mobileの判定は、ユーザーの設定次第で変わる。
  • また常に「iPadである」と特定できるuser agentは無いので、wp_is_mobileをカスタマイズしてもどうにもならない。

「iPad Safari is_moile」等で探すとたくさん見つかる記事の通り。

 

アップルはなぜこうしているか、をどこかの記事で見かけた気がするのですが、URLを失念。

たしかこんな感じだったと記憶しています。

十分に大きいスクリーンでは、(タッチデバイスであっても)PC用サイトを表示すべき

 

一方グーグルは、

スマートフォン、タブレットでは、mobile用サイトを表示すべき

のようなことを言っていると思う。(mobileに最適化されたサイト、だったかな?)

参考:user agent(Safari)のコピペ

古いiPad Air

Mozilla/5.0 (iPad; CPU OS 12_5_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.1.2 Mobile/15E148 Safari/604.1

第4世代iPad Air
  • デフォルト
    Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.2 Safari/605.1.15
  • 「デスクトップ用Webサイトを表示」をオフ
    Mozilla/5.0 (iPad; CPU OS 15_2_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.2 Mobile/15E148 Safari/604.1
iPhoneXS
  • デフォルト
    Mozilla/5.0 (iPhone; CPU iPhone OS 15_2_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.2 Mobile/15E148 Safari/604.1
  • 「デスクトップ用Webサイトを表示」をオン
    Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.2 Safari/605.1.15

サブメニューの挙動

wp_is_mobileで色々制御していて、SafariとChromeの違いで一番困るのがサブメニュー付きのナビゲーション。

 

構文は、ワードプレス標準のメニューと仮定して、、

  • CSS :hoverでサブメニューの出し入れ、アンカーの挙動をdoubletaptogoなど制御している場合、古いiPadやAndroidでは期待通り動く。
  • 新しいiPadでは、タップでサブメニューは開くが、この状態でさらに2回タップしないと遷移しない。(tripletaptogoになっちゃう)

ほかにも、親項目が「<a>アンカー</a>」だとサブメニューが開かなかったり、bodyのタップでサブメニューが閉じたり閉じなかったり、と色々。

今のところ、新旧iPadで期待通り動くスクリプト

jQuery(document).ready(function(){
	jQuery('#navigation-menu ul li').hover(function(){
		jQuery('ul:not(:animated)', this).slideDown(100);
	}, function(){
		jQuery('ul.sub-menu', this).slideUp(100);
	});
	jQuery('#page').on('click', function(e){
		jQuery('ul.sub-menu', this).slideUp(100);
	});
});

#navigation-menuは、メニューのラッパー。メニュー名で左右されたくないので。

範囲外をタップで閉じるようにしていますが、「body」だと閉じないので、ひとつ内側のラッパー(ここでは#pageにしてますが、テーマによってマチマチなはず。)にしています。

参考記事:jQuery: ドロップダウンメニューの作り方

キャッシュ

Is_mobileの判定でいろいろやってる場合、SafariChromeを行ったり来たりすると、キャッシュによってis_mobile状態も維持されて非常に不安定。

キャッシュ関係のプラグインは一切なし。

 

同じURLを違うブラウザでしつこく閲覧する、という開発者ならではの行動なので、それほど気にしなくていいとは思うけど、、、

キャッシュ共有の仕組みは調べてもよくわからない。AMPなんとか??

新しいiPadでも、SafariとChromeの表示を常に合わせる

メディアクエリー・スクリーンサイズでの振り分けが一番簡単ですが、ナニカ事情がある場合。

1、Safariでも常にハンバーガーを出す

JavaScriptのタッチデバイス判定だけ。簡単で、動作も一番確実だと思います。

  • タッチデバイスではハンバーガー
  • 非タッチデバイスではPC用
1-b、「IE非対応」で良ければ

IE無視なら、JacaScript不要、メディアクエリーだけでも処理できます。

PC用	{
	display: none;
}
ハンバーガー	{
	display: block;
}
@media ( hover: hover ) and ( pointer: fine )	{
	PC用	{
		display: block;
	}
	ハンバーガー	{
		display: none;
	}
}

    タッチデバイス判定や、:hoverに関するあれやこれやも簡単に処理できるので、これからは多用しそう。

     

    参考:下記記事で詳しく解説されています。いろいろ出来るのね~。

    CSSのメディアクエリを使ってレスポンシブに対応させる書き方

      2、ChromeでもPC用ナビを出す

      これはかなり面倒だし、よくよく検証しないとアブない。

      • タッチデバイスではハンバーガー
      • 非タッチデバイスではPC用ナビ
      • user agentに「iPad」が出現していて、かつスクリーン短辺が820px~ならば、例外的にPC用ナビ(OSのバージョンでもいいかもだけど、どっちが長期間確実かなぁ??わからん。)
      2-b、縦位置ではハンバーガーを出す

      さらに「縦位置ではハンバーガーを出す」なら更に縦横条件を追加するわけだけど、今度はSafari用にも指示が必要

      こっちにはキーワード「iPad」が出現しない可能性大なので、

      • タッチデバイス
      • user agentにMacintoshまたはiPadが出現
      • スクリーン短辺が820px~
      • 縦位置

      を満たすように条件づければいいはず。ややこしいね。

      さらにさらに

      ナビゲーションを上部に固定するような場合、ページ内遷移用にスクリプトを使うケースが多いと思います。

      これもハンバーガー・PC用ナビで多少の差があるはずなので、スクリプトにも条件分岐を入れて切り替えなきゃならない。

      JavaScript、なんちゃってメディアクエリー

      screenじゃなくてwindowでやればもっと簡単ですが、CSSやディベロッパーツールと合わせたかったので。

      jQuery(function(){
      	var screenWidth = screen.width;
      	var screenHeight = screen.height;
      	if ( screenWidth <= screenHeight ) {
      		var screenLongSide = screenHeight;
      		var screenShortSide = screenWidth;
      	} else {
      		var screenLongSide = screenWidth;
      		var screenShortSide = screenHeight;
      	}
      	var breakPointMiddle = 768;
      	var orient = window.onorientation;
      	if( Math.abs( window.orientation ) === 0 || Math.abs( window.orientation ) === 180 ){
      		if ( screenShortSide > breakPointMiddle ){
      			var view_wide = 'wide';
      		} else {
      			var view_wide = 'narrow';
      		}
      	} else {
      		if ( screenLongSide > breakPointMiddle ){
      			var view_wide = 'wide';
      		} else {
      			var view_wide = 'narrow';
      		}
      	}
      	/* ---------- デバイス水平方向幅で分岐 ---------- */
      	if ( view_wide === 'narrow' ) {
      		var headerHight = 65;
      	} else {
      		var headerHight = 105;
      	}
      });

      スムーススクロールの余白切り替えなどに。

      ハンバーガー、PC用ナビの高さを同じにしちゃう、って手もあるけど、、、

       

      「Jquery依存スクリプトでブレークポイント使ってるの、あったなぁ」と思いだして調べてみると、やっぱりあった。

      「window.matchMedia」だけで出来るのね。


      :hoverイミュレーションを検知できないのかな、と思って少し検索すると、それっぽい記事がわんさか見つかる。古いiOSでの不具合とか、むしろ:hoverを無効にしたいとか。議論の種だったのね。

      「タッチしたつもりなのに遷移しない」と感じることが多いけど、これか。

      キチンと調べたら、この記事も色々ひっくり返りそう。


      ※余談。JavaScriptの判定をそのままphpの関数に出来たらかなり便利な気がしますが、ajaxを使わないと無理みたいで手に余る。でもそのうちチャレンジしてみようかな。


      キリがないので、結局JavaScriptのスクリーン幅判定だけで制御することにしました。

      • ナビゲーションについては、でかければPC用・小さければハンバーガー
      • サブメニューはタッチデバイスでもどうにか動かす。
      • wp_is_mobileは一切使わない

       

      まだまだスッキリはしていませんが、ひとまずここでひと区切り。

      発見・再認識がたくさんありました。