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

おすすめ購読元

博客园 - 司徒正美
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

阮一峰的网络日志

科技爱好者周刊(第 396 期):互联网通信的替代方案 科技爱好者周刊(第 396 期):互联网通信的替代方案 - 阮一峰的网络日志 科技爱好者周刊(第 395 期):软件开发的第三种方式 科技爱好者周刊(第 395 期):软件开发的第三种方式 - 阮一峰的网络日志 科技爱好者周刊(第 393 期):脑腐状态 科技爱好者周刊(第 392 期):axios 投毒与好莱坞式骗术 科技爱好者周刊(第 391 期):AI 的贫富分化 科技爱好者周刊(第 390 期):没有语料,大模型就是智障 套壳中国大模型撑起500亿美元估值?扒一扒 Cursor 的"套壳"疑云 科技爱好者周刊(第 389 期):未来如何招聘程序员 科技爱好者周刊(第 388 期):测试是新的护城河 零安装的"云养虾":ArkClaw 使用指南 科技爱好者周刊(第 387 期):你是领先的 科技爱好者周刊(第 386 期):当外卖员接入 AI 字节全家桶 Seed 2.0 + TRAE 玩转 Skill 科技爱好者周刊(第 385 期):马斯克害怕中国车企吗? 智谱旗舰 GLM-5 实测:对比 Opus 4.6 和 GPT-5.3-Codex 科技爱好者周刊(第 384 期):为什么软件股下跌 科技爱好者周刊(第 383 期):你是第几级 AI 编程 Kimi 的一体化,Manus 的分层 科技爱好者周刊(第 382 期):独立软件的黄昏 AI native Workspace 也许是智能体的下一阶段 科技爱好者周刊(第 381 期):中国 AI 大模型领导者在想什么 科技爱好者周刊(第 380 期):为什么人们拥抱"不对称收益" 科技爱好者周刊(第 379 期):《硅谷钢铁侠》摘录 我如何用 AI 处理历史遗留代码:MiniMax M2.1 升级体验 科技爱好者周刊(第 378 期):预测是新的互联网热点 科技爱好者周刊(第 377 期):14万美元的贫困线 科技爱好者周刊(第 376 期):太空数据中心的争议 科技爱好者周刊(第 375 期):一扇门的 Bug 终于有人做了 Subagent,TRAE 国内版 SOLO 模式来了 科技爱好者周刊(第 374 期):6GHz 的问题 VS Code 使用国产大模型 MiniMax M2 教程 科技爱好者周刊(第 373 期):数据模型是新产品的核心 国产大模型接入 Claude Code 教程:以 Doubao-Seed-Code 为例 科技爱好者周刊(第 372 期):软件界面如何设计 大模型比拼:MiniMax M2 vs GLM 4.6 vs Claude Sonnet 4.5 科技爱好者周刊(第 371 期):一个乐观主义者的专访 科技爱好者周刊(第 370 期):正确的代码高亮 错误处理:异常好于状态码 科技爱好者周刊(第 369 期):Tim 与罗永浩的对谈 科技爱好者周刊(第 368 期):不要这样管理软件团队 一天之内,智谱和 Anthropic 都发了最强编程模型 科技爱好者周刊(第 367 期):Nano Banana 的几个妙用 科技爱好者周刊(第 366 期):旧金山疯狂的 AI 广告 科技爱好者周刊(第 365 期):流量变现正在崩塌 科技爱好者周刊(第 364 期):最难还原的魔方 科技爱好者周刊(第 363 期):最好懂的神经网络解释 科技爱好者周刊(第 362 期):GitHub 工程师谈系统设计 科技爱好者周刊(第 361 期):暗网 Tor 安全吗?
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) {
  // 当前设备是移动设备
}

(完)