慣性聚合 関心のあるブログ、ニュース、テクノロジーを効率的に追跡
原文を読む 慣性聚合で開く

おすすめ購読元

博客园 - 司徒正美
V
V2EX
T
Tailwind CSS Blog
有赞技术团队
有赞技术团队
aimingoo的专栏
aimingoo的专栏
Apple Machine Learning Research
Apple Machine Learning Research
IT之家
IT之家
Blog — PlanetScale
Blog — PlanetScale
A
About on SuperTechFans
月光博客
月光博客
T
The Blog of Author Tim Ferriss
宝玉的分享
宝玉的分享
Martin Fowler
Martin Fowler
博客园 - 聂微东
The GitHub Blog
The GitHub Blog
V
Visual Studio Blog
WordPress大学
WordPress大学
酷 壳 – CoolShell
酷 壳 – CoolShell
Engineering at Meta
Engineering at Meta
GbyAI
GbyAI

阮一峰的网络日志

記事がありません

JavaScriptでスマートフォンブラウザを検知する5つの方法
阮一峰 · 2021-09-29 · via 阮一峰的网络日志

時々、フロントエンドのウェブページには、ユーザーが携帯ブラウザを使用しているかデスクトップブラウザを使用しているかを知る必要があります。

本稿はStackOverflowを基に、JavaScriptで携帯ブラウザを検知する5つの方法をまとめました。

一、navigator.userAgent

最も簡単な方法は、ブラウザのuser agent文字列を分析することです。この文字列にはデバイス情報が含まれています。

JSはnavigator.userAgent属性を通じてこの文字列を取得し、mobiandroidiphoneなどのキーワードが含まれているかどうかで、携帯デバイスと判断できます。


if (/Mobi|Android|iPhone/i.test(navigator.userAgent)) {
  // 当前设备是移动设备
}

// 另一种写法
if (
  navigator.userAgent.match(/Mobi/i) ||
  navigator.userAgent.match(/Android/i) ||
  navigator.userAgent.match(/iPhone/i)
) {
  // 当前设备是移动设备
}

この方法の利点は簡単で便利だが、欠点は信頼性が低いことです。ユーザーはこの文字列を変更して、スマートフォンブラウザをデスクトップブラウザに偽装することができます。

Chromiumシリーズのブラウザには、navigator.userAgentDataという属性もあります。これも似たような機能を持っています。違いは、ユーザーエージェント文字列をオブジェクトとして解析し、そのmobile属性が、ユーザーがモバイルデバイスを使用しているかどうかを示すブーリアン値を返す点です。


const isMobile = navigator.userAgentData.mobile; 

注意点として、AppleのSafariブラウザとFirefoxブラウザはこの属性をサポートしていません。詳細はCaniuseウェブサイトで確認できます。

さらに、もう廃止されたnavigator.platform属性もあります。すべてのブラウザがサポートしているので、これも利用できます。これはユーザーのオペレーティングシステムを示す文字列を返します。


if (/Android|iPhone|iPad|iPod/i.test(navigator.platform)) {
  // 当前设备是移动设备
}

二、window.screen、window.innerWidth

別の方法として、画面の幅でスマートフォンかどうかを判断する方法がある。

window.screenこのオブジェクトはユーザーのデバイスの画面情報を返し、このオブジェクトのwidthプロパティは画面の幅(ピクセル単位)である。


if (window.screen.width < 500) {
  // 当前设备是移动设备 
}

上記の例では、画面の幅window.screen.widthが500ピクセル未満の場合、スマートフォンと判断される。

この方法の欠点は、スマートフォンを横に使う場合に認識できない点にある。

別のプロパティwindow.innerWidthはブラウザのウィンドウ内のウェブページの表示部分の幅を返し、異なる幅でウェブページのスタイルを指定するのに適している。


const getBrowserWidth = function() {
  if (window.innerWidth < 768) {
    return "xs";
  } else if (window.innerWidth < 991) {
    return "sm";
  } else if (window.innerWidth < 1199) {
    return "md";
  } else {
    return "lg";
  }
};

三、window.orientation

第三の方法は画面の向きを検知する方法です。携帯電話の画面はいつでも方向を変えることができます(横画面または縦画面)。デスクトップデバイスはできません。

window.orientation属性は現在の画面の方向を取得するために使用され、この属性はモバイルデバイスにのみ存在します。デスクトップデバイスではundefinedが返されます。


if (typeof window.orientation !== 'undefined') {
  // 当前设备是移动设备 
}

注意点として、iPhoneのSafariブラウザはこの属性をサポートしていません。

四、touchイベント

第四の方法は、携帯電話ブラウザのDOM要素がontouchstart属性を通じて、touchイベントにリスナー関数を指定できることです。デスクトップデバイスにはこの属性はありません。


function isMobile() { 
  return ('ontouchstart' in document.documentElement); 
}

// 另一种写法
function isMobile() {
  try {
    document.createEvent("TouchEvent"); return true;
  } catch(e) {
    return false; 
  }
}

五、window.matchMedia()

最後の方法はCSSと組み合わせて判断する方法です。

CSS はメディアクエリ(媒体查询)を通じて、ウェブページにレスポンシブなスタイルを指定します。あるメディアクエリのステートメントがスマートフォン用であれば、現在のデバイスはモバイルデバイスであると判断できます。

window.matchMedia()メソッドは、CSS のメディアクエリのステートメントを引数として受け取り、そのステートメントが有効かどうかを判断します。


let isMobile = window.matchMedia("only screen and (max-width: 760px)").matches;

上記の例では、window.matchMedia()の引数はCSSのクエリステートメントで、画面幅が700ピクセル以下のデバイスにのみ有効です。これにより、オブジェクトが返され、そのmatchesプロパティはブーリアン値です。trueが__JHSNS_SEG_4380fe82_46__であれば、クエリが有効であり、現在のデバイスはスマートフォンです。

画面幅だけでなく、ポインターの精度で判断することもできます。


let isMobile = window.matchMedia("(pointer:coarse)").matches;

上記の例では、CSS ステートメントpointer:coarseは現在のデバイスのポインタが不精密であることを示します。スマートフォンはマウスをサポートせず、タッチのみをサポートするため、この条件に合致します。

は一部のデバイスでは複数のポインタをサポートしており、例えばマウスとタッチの両方を同時にサポートしています。pointer:coarseは主なポインタを判断するために使用され、さらにany-pointerコマンドはすべてのポインタを判断します。


let isMobile = window.matchMedia("(any-pointer:coarse)").matches;

の例では、any-pointer:coarseはすべてのポインタの中で少なくとも一つが不精密であれば、検索条件に合致することを示します。

六、ツールキット

上記の方法以外にも、他人が書いたツールキットを使用することもできます。ここではreact-device-detectを推奨します。これは複数の粒度のデバイス検知をサポートしています。


import {isMobile} from 'react-device-detect';

if (isMobile) {
  // 当前设备是移动设备
}

(完)