Help us understand the problem. What is going on with this article?

JavaScript: ブラウザを開いているのがPCかモバイルかを切り分ける ー とくにタッチ操作に絡む場合

01 User-Agentを使う

ブラウザを開いているのがWindows PCやMacなのか、モバイル端末なのかはwindow.navigator.userAgentで調べられます。User-Agentはつぎのような構文の文字列です。

<product> / <product-version> <comment>

webブラウザの一般的な書式はつぎのとおりで、platformがオペレーティングシステム(OS)を示します。PCあるいはMacの場合に含まれる文字列は、それぞれWindowsMacintoshです。Linuxの場合はモバイルもあり得ますので、もう少し細かく調べなければなりません。本稿では省くことにします。

Mozilla/<version> (<system-information>) <platform> (<platform-details>) <extensions>

確かめ方としては、navigator.userAgentの戻り値にplatformの文字列が含まれるか調べればよいでしょう。

const agent = navigator.userAgent.toLowerCase();
if (agent.includes('windows')) {
    console.log('Windows');
} else if (agent.includes('macintosh')) {
    console.log('Mac');
} else {
    console.log('mobile');
}

もっとも、MDNのリファレンスには、つぎのような脅迫めいた「注記」が加えられています。

ユーザエージェントを表す文字列を検出することに基づいたブラウザ識別は、信頼できないものであり、また、推奨されません。なぜなら、ユーザエージェントを表す文字列は、ユーザによって変更することができるからです。

02 判定に同時タッチコンタクト数を加える

あえてユーザエージェントを書き替えるユーザーが多いとも思えません。けれど、保険をかけるに越したことはないでしよう。そこで使ったのが、Navigator.maxTouchPointsです。タッチパネルがなければ、数値0が戻り値です。タッチパネルが備わっていないLinuxデスクトップも拾えます。

つぎのようなサンプルコードを書いてみました。併せて、試していただけるよう、CodePenにも掲げます(サンプル001)。

const info = getDeviceInfo();
const result = (info.windows || info.mac || info.touchPoints === 0) ? 'PC!' : 'mobile';
console.log(result);
function getDeviceInfo() {
    const agent = navigator.userAgent.toLowerCase();
    const touchPoints = ('maxTouchPoints' in navigator) ? navigator.maxTouchPoints : 0;
    const result = {
        windows: agent.includes('windows'),
        mac: agent.includes('macintosh'),
        linux: agent.includes('linux'),
        touchPoints: touchPoints
    }
    return result;
}

サンプル001■JavaScript: Evaluating PC or mobile

See the Pen JavaScript: Evaluating PC or mobile by Fumio Nonaka (@FumioNonaka) on CodePen.

なお、今回はタッチ操作に関わってPCとモバイルを切り分けました。画面サイズやレイアウトを考えるときは、また少し違ってくるでしょう。ユーザーエージェントに頼らない手法については、MDN「ユーザーエージェント文字列を用いたブラウザーの判定」が参考になります。たとえば、以下の引用は画面サイズの場合です。

画面のサイズについては、window.innerWidthwindow.addEventListener("resize", function(){ /*refresh screen size dependent things*/ })を使用するだけです。

[注記: 2019/11/29] 文字列が含まれるかどうか調べるメソッドを、indexOf()からECMAScript 2015のincludes()に差し替えた。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした