ตรวจสอบว่าอุปกรณ์เป็น iOS


408

ฉันสงสัยว่าเป็นไปได้หรือไม่ที่จะตรวจพบว่าเบราว์เซอร์นั้นทำงานบน iOS หรือไม่เหมือนกับวิธีที่คุณสามารถตรวจจับคุณสมบัติด้วย Modernizr (แม้ว่าจะเป็นการตรวจจับอุปกรณ์ที่ชัดเจนมากกว่าการตรวจจับคุณสมบัติ)

ปกติฉันจะชอบการตรวจจับคุณสมบัติแทน แต่ฉันต้องค้นหาว่าอุปกรณ์เป็น iOS เพราะวิธีที่พวกเขาจัดการวิดีโอตามคำถามนี้หรือไม่YouTube API ไม่ทำงานกับอุปกรณ์ iPad / iPhone / ไม่ใช่ Flash


ดู [สตริงตัวแทนผู้ใช้ iOS 5 คืออะไร] [1] (ซ้ำกัน) [1]: stackoverflow.com/questions/7825873/…
dejuknow

1
การตรวจจับฝั่งไคลเอ็นต์หรือฝั่งเซิร์ฟเวอร์นี้หรือไม่
Douglas Greenshields

เฮ้ @DouglasGreenshields เป็นฝั่งไคลเอ็นต์
SparrwHawk

1
นอกจากนี้ไม่ซ้ำกันฉันถามวิธีการทำ ฉันไม่เคยใช้ตัวแทนผู้ใช้ในการดมกลิ่นมาก่อน
SparrwHawk

คำตอบ:


821

กำลังตรวจจับ iOS

ฉันไม่ใช่แฟนของ User Agent ที่ดมกลิ่น แต่นี่คือวิธีที่คุณจะทำ:

var iOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;

อีกวิธีหนึ่งคือการพึ่งพาnavigator.platform:

var iOS = navigator.platform && /iPad|iPhone|iPod/.test(navigator.platform);

iOSจะเป็นอย่างใดอย่างหนึ่งtrueหรือfalse

ทำไมไม่ MSStream

Microsoft ฉีดคำว่าiPhoneใน IE11 userAgentเพื่อที่จะพยายาม Gmail อย่างใดอย่างหนึ่ง ดังนั้นเราต้องแยกมันออก ข้อมูลเพิ่มเติมเกี่ยวกับเรื่องนี้ที่นี่และที่นี่

ด้านล่างเป็นการอัปเดตของ IE11 userAgent(Internet Explorer สำหรับ Windows Phone 8.1 Update):

Mozilla / 5.0 (มือถือ; Windows Phone 8.1; Android 4.0; ARM; Trident / 7.0; Touch; rv: 11.0; IEMobile / 11.0; NOKIA; Lumia 930) เช่น iPhone OS 7_0_3 Mac OS X AppleWebKit / 537 (KHTML เช่น Gecko) มือถือ Safari / 537


เพิ่มอุปกรณ์ได้ง่ายขึ้นโดยไม่ต้องใช้นิพจน์ปกติ:

function iOS() {

  var iDevices = [
    'iPad Simulator',
    'iPhone Simulator',
    'iPod Simulator',
    'iPad',
    'iPhone',
    'iPod'
  ];

  if (navigator.platform) {
    while (iDevices.length) {
      if (navigator.platform === iDevices.pop()){ return true; }
    }
  }

  return false;
}

iOS()จะเป็นอย่างใดอย่างหนึ่งtrueหรือfalse

หมายเหตุ:ทั้งสองnavigator.userAgentและnavigator.platformสามารถแกล้งโดยผู้ใช้หรือส่วนขยายเบราว์เซอร์


กำลังตรวจหาเวอร์ชั่น iOS

วิธีที่ใช้กันมากที่สุดของการตรวจสอบเวอร์ชัน iOS ของคุณคือการแยกจากสตริงตัวแทนผู้ใช้ แต่ยังมีการอนุมานการตรวจจับคุณสมบัติ* ;

เรารู้ถึงข้อเท็จจริงที่history APIนำมาใช้ในiOS4 - matchMedia APIในiOS5 - webAudio APIในiOS6 - WebSpeech APIในiOS7และอื่น ๆ ..

หมายเหตุ:รหัสต่อไปนี้ไม่น่าเชื่อถือและจะแตกถ้าคุณลักษณะ HTML5 เหล่านี้ถูกคัดค้านใน iOS เวอร์ชันที่ใหม่กว่า คุณได้รับการเตือน!

function iOSversion() {

  if (/iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream) {
    if (window.indexedDB) { return 'iOS 8 and up'; }
    if (window.SpeechSynthesisUtterance) { return 'iOS 7'; }
    if (window.webkitAudioContext) { return 'iOS 6'; }
    if (window.matchMedia) { return 'iOS 5'; }
    if (window.history && 'pushState' in window.history) { return 'iOS 4'; }
    return 'iOS 3 or earlier';
  }

  return 'Not an iOS device';
}

2
ขอบคุณ Pierre - รหัสนี้ดูเรียบง่ายขึ้นฉันแค่สงสัยว่าฉันสามารถระบุ 'iOS' ได้แทนที่จะต้องพิมพ์ iDevices แยกทั้งหมด .... ถ้า ((navigator.userAgent.match (/ iPhone / i)) | | (navigator.userAgent.match (/ iPod / i)) || (navigator.userAgent.match (/ iPad / i)))) {// ทำอะไรบางอย่าง}
SparrwHawk

9
สิ่งที่คุณทำในตัวอย่างที่สองคือการอนุมานคุณลักษณะไม่ใช่การตรวจจับคุณสมบัติ การตรวจจับคุณสมบัติคือการทดสอบคุณสมบัติที่คุณจะใช้จริง ๆ ในขณะที่สิ่งที่คุณกำลังทำอยู่คือการทดสอบคุณสมบัติที่คุณรู้ว่ามีการเปิดตัวในระบบปฏิบัติการรุ่นใดรุ่นหนึ่งโดยเฉพาะ สิ่งนี้มีความเปราะบางเนื่องจาก iOS เวอร์ชันในอนาคตสามารถลบคุณลักษณะเหล่านี้ได้
Tim Down

23
นี่เป็นวิธีที่ดีกว่าในการเขียนเช็คของคุณ:var iOS = /(iPad|iPhone|iPod)/g.test(navigator.userAgent);
LandonSchropp

5
เพียงทราบ - อาร์เรย์ navigator.platform ไม่ทำงานบน iPad Simulator เพราะมันมีทั้งวลี "iPad Simulator" ในสตริงแพลตฟอร์ม
Kevin Newman

9
จาก iOS 13 เอเจนต์ผู้ใช้ของ iPad ได้เปลี่ยนเป็น "Mac OS" ตัวอย่างเช่น: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0 Safari/605.1.15ดังนั้นคำตอบนี้จำเป็นต้องได้รับการอัปเดต
zvi

38

หลังจาก iOS 13 คุณควรตรวจจับอุปกรณ์ iOS เช่นนี้เนื่องจาก iPad จะไม่ถูกตรวจพบว่าเป็นอุปกรณ์ iOS ด้วยวิธีเก่า (เนื่องจากตัวเลือก "เดสก์ท็อป" ใหม่ซึ่งเปิดใช้งานตามค่าเริ่มต้น):

let isIOS = /iPad|iPhone|iPod/.test(navigator.platform)
|| (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1)

เงื่อนไขแรกสำหรับ iOS <13 หรือ iPhone หรือ iPad ที่ปิดใช้งานโหมดเดสก์ท็อปเงื่อนไขที่สองสำหรับ iPadOS 13 ในการกำหนดค่าเริ่มต้นเนื่องจากวางตำแหน่งตัวเองเช่น Macintosh Intel แต่จริงๆแล้วเป็น Macintosh เดียวที่มีมัลติทัช

ค่อนข้างแฮ็คมากกว่าทางออกที่แท้จริง แต่ทำงานได้อย่างน่าเชื่อถือสำหรับฉัน

ป.ล.ตามที่กล่าวไว้ก่อนหน้านี้คุณอาจเพิ่มการตรวจสอบ IE

let isIOS = (/iPad|iPhone|iPod/.test(navigator.platform) ||
(navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1)) &&
!window.MSStream

ทำไมไม่ใช้navigator.userAgentสำหรับการตรวจสอบนี้/iPad|iPhone|iPod/.test(navigator.platform)? ดูเหมือนว่าnavigator.platformจะส่งคืน 'MacIntel' สำหรับ iPhone iOS <= 12
Charis Theo

@CharisTheo เพราะ iPad ไม่ได้อยู่ใน userAgent ใน iOS> = 13
Kzrbill

แต่คุณกำลังตรวจสอบ iPad iOS> = 13 ในการตรวจสอบครั้งที่สองหรือฉันขาดอะไรไป?
Charis Theo

navigator.maxTouchPointsไม่รองรับ iOS ดังนั้นการตรวจสอบจะไม่ทำอะไรให้คุณเลย
PaulC

@PaulC คุณถูกต้องใน maxTouchPoints นั้นไม่ได้กำหนดสำหรับ iOS 12 และต่ำกว่า แต่ kikiwora อยู่ในเส้นทางที่ถูกต้องเนื่องจาก maxTouchPoints รองรับใน iOS 13 ดูคำตอบของฉัน
Bob Arlof

14

ชุดนี้ตัวแปร_iOSDeviceที่จะเป็นจริงหรือเท็จ

_iOSDevice = !!navigator.platform.match(/iPhone|iPod|iPad/);

3
อะไรนะ !! ทำ?
patrick

4
@astronought ลบล้างคู่จะใช้ในการหล่อแบบบูล
Vitim.us

2
@astronought bang bang คุณเป็นบูลีน: D
Qback

1
การใช้/iPhone|iPod|iPad/.test(navigator.platform)คุณสามารถหลีกเลี่ยง!!
lionello

10

หากคุณใช้Modernizrคุณสามารถเพิ่มการทดสอบแบบกำหนดเองได้

ไม่สำคัญว่าคุณจะเลือกใช้โหมดตรวจจับแบบใด (userAgent, navigator.vendor หรือ navigator.platform) คุณสามารถสรุปได้เพื่อการใช้งานที่ง่ายขึ้นในภายหลัง

//Add Modernizr test
Modernizr.addTest('isios', function() {
    return navigator.userAgent.match(/(iPad|iPhone|iPod)/g);
});

//usage
if (Modernizr.isios) {
    //this adds ios class to body
    Modernizr.prefixed('ios');
} else {
    //this adds notios class to body
    Modernizr.prefixed('notios');
}

2
ระวังตัวให้ทันสมัยตัวพิมพ์เล็กจะเป็นตัวพิมพ์เล็กของชื่อของการทดสอบที่เพิ่มเข้ามาโดยอัตโนมัติ (ในตัวอย่างของคุณ Modernizr.isiOS จะไม่มีวันคืนจริง) พฤติกรรมที่ไม่ดีของ lib ในมุมมองของฉัน ...
Cétia

3
แจ้งให้ทราบล่วงหน้าเพียงเล็ก ๆ : คุณสามารถลดความซับซ้อนของreturn x ? true : falseการreturn Boolean(x)หรือเพียงแค่return !!x
tibalt


6

เวอร์ชันที่เรียบง่ายและง่ายต่อการขยาย

var iOS = ['iPad', 'iPhone', 'iPod'].indexOf(navigator.platform) >= 0;

1
หากคุณยังต้องการการทำงานบน iOS Simulator navigator.platform.replace(' Simulator', '')คุณสามารถใช้:
Koraktor

แต่มันใช้งานไม่ได้สาเหตุ['str'].indexOf('string') == -1
tibalt

navigator.platform จะว่า 'iPad', 'iPhone' หรือ 'iPod' เว้นแต่จำลองทำงาน
Kory Nunn

4

อาจเป็นการตอบรับที่คุ้มค่าว่า iPads ที่ใช้ iOS 13 จะถูกnavigator.platformตั้งค่าไว้MacIntelซึ่งหมายความว่าคุณจะต้องหาวิธีอื่นในการตรวจหาอุปกรณ์ iPadOS


3

ฉันเขียนสิ่งนี้เมื่อสองสามปีก่อน แต่ฉันเชื่อว่ายังใช้งานได้:

if(navigator.vendor != null && navigator.vendor.match(/Apple Computer, Inc./) && navigator.userAgent.match(/iPhone/i) || (navigator.userAgent.match(/iPod/i))) 

    {

        alert("Ipod or Iphone");

    }

else if (navigator.vendor != null && navigator.vendor.match(/Apple Computer, Inc./) && navigator.userAgent.match(/iPad/i))  

    {

        alert("Ipad");

    }

else if (navigator.vendor != null && navigator.vendor.match(/Apple Computer, Inc./) && navigator.userAgent.indexOf('Safari') != -1)

    {

        alert("Safari");

    }

else if (navigator.vendor == null || navigator.vendor != null)

    {

        alert("Not Apple Based Browser");

    }

2

ตัวแทนผู้ใช้บนอุปกรณ์ iOS พูดถึง iPhone หรือ iPad ฉันแค่กรองตามคำหลักเหล่านั้น


4
นอกจากนี้ยังมี iPod Touches ที่ต้องพิจารณา
Douglas Greenshields

@DouglasGreenshields ถูกต้อง ลืมเกี่ยวกับสิ่งนั้น แต่ฉันเชื่อว่ามันส่งตัวตนในตัวแทนผู้ใช้เช่นกัน
ไบรอัน Naegele

ตัวแทนผู้ใช้ของซาฟารี iPad จะไม่รวม "iPad" จาก iPadOS 13 อีกต่อไป
จอนนี่

2

เมื่อใดก็ตามที่เป็นไปได้เมื่อเพิ่มการทดสอบ Modernizr คุณควรเพิ่มการทดสอบสำหรับคุณสมบัติมากกว่าอุปกรณ์หรือระบบปฏิบัติการ ไม่มีอะไรผิดปกติกับการเพิ่มสิบการทดสอบทั้งหมดสำหรับ iPhone หากเป็นไปได้ ตรวจพบคุณสมบัติบางอย่างไม่ได้

    Modernizr.addTest('inpagevideo', function ()
    {
        return navigator.userAgent.match(/(iPhone|iPod)/g) ? false : true;
    });

ตัวอย่างเช่นบน iPhone (ไม่ใช่ iPad) วิดีโอไม่สามารถเล่นแบบอินไลน์บนเว็บเพจมันจะเปิดขึ้นเต็มหน้าจอ ดังนั้นฉันจึงสร้างการทดสอบ 'no-inpage-video'

จากนั้นคุณสามารถใช้สิ่งนี้ใน css (Modernizr เพิ่มคลาส.no-inpagevideoให้กับ<html>แท็กหากการทดสอบล้มเหลว)

.no-inpagevideo video.product-video 
{
     display: none;
}

นี่จะเป็นการซ่อนวิดีโอบน iPhone (สิ่งที่ฉันทำในกรณีนี้คือการแสดงภาพทางเลือกด้วยการคลิกเพื่อเล่นวิดีโอ - ฉันไม่ต้องการให้เครื่องเล่นวิดีโอเริ่มต้นและปุ่มเล่นปรากฏขึ้น)


ตอนนี้ iOS10 playsinlineสามารถใช้งานได้แล้วดังนั้นคุณสามารถใช้'playsInline' in document.createElement('video');เป็นแบบทดสอบได้ตอนนี้ github.com/Modernizr/Modernizr/issues/2077
Simon_Weaver

2

ว้าวรหัสเล่ห์เหลี่ยมจำนวนมากที่นี่ ทำให้มันง่ายหน่อย!

อันนี้ IMHO รวดเร็วประหยัดและทำงานได้ดี:

 iOS = /^iP/.test(navigator.platform);

 // or, more future-proof (in theory, probably not in practice):

 iOS = /^iP(hone|[ao]d)/.test(navigator.platform);

 // or, if you prefer readability:

 iOS = /^(iPhone|iPad|iPod)/.test(navigator.platform);
  • มันเร็วเพราะ regexp ตรวจสอบตำแหน่งของ tarting ^ของสตริงแพลตฟอร์มก่อนและหยุดหากไม่มี "iP" (เร็วกว่าการค้นหาสตริง UA ที่ยาวจนถึงตอนท้าย)
  • ปลอดภัยกว่าการตรวจสอบ UA (สมมติว่า navigator.platform มีโอกาสปลอมน้อยกว่า)
  • ตรวจจับ iPhone / iPad Simulator


อัพเดท: สิ่งนี้ไม่ครอบคลุมถึง iPad ในโหมดเดสก์ท็อป (และเป็นค่าเริ่มต้นของ iPadOS 13)
ไม่เป็นไรสำหรับคุณดูคำตอบของ Justin และ kikiwora


iOS = /^(iPhone|iPad|iPod)/.test(navigator.platform);มากกว่านี้ฉันจะทำ iOS = /^(iPhone|iPad|iPod)/.test(navigator.userAgent || navigator.vendor || navigator.platform); ตามทางเลือกวัด cuz ในกรณี navigator.platform ของฉันไม่ทำงาน แต่การทำเช่นนี้ทำงานได้ดีในภายหลัง
Coderboi

navigator.platformไม่ทำงานหรอ ถ้าอย่างนั้นคุณเป็น iOS จริงๆหรือ ตรวจสอบกับjeka.info/test/navigator.html userAgentให้ผลบวกที่ผิดเนื่องจากผู้ค้าบางรายปลอมให้เลียนแบบอุปกรณ์ Apple ไม่ว่าด้วยเหตุผลใด vendorเพียงแค่ผลตอบแทนอย่างใดอย่างหนึ่งGoogle Inc., Apple Computer, Inc.หรืออะไร (ใน Firefox)
jj

1

อัปเดตคำตอบแรกเล็กน้อยโดยใช้วิธีการทำงานที่มากขึ้น

    const isIOS = [
      'iPad Simulator',
      'iPhone Simulator',
      'iPod Simulator',
      'iPad',
      'iPhone',
      'iPod',
    ].indexOf(navigator.platform) !== -1;

ไม่ทำงานในเครื่องมือจำลองมือถือ Brave / Chrome dev ฉันได้รับMacIntel
sdfsdf

1

ไม่มีคำตอบก่อนหน้านี้ที่นี่ทำงานได้กับเบราว์เซอร์ที่สำคัญทั้งหมดใน iOS ทุกรุ่นรวมถึง iOS 13 นี่คือโซลูชันที่ใช้งานได้กับ Safari, Chrome และ Firefox สำหรับ iOS ทุกเวอร์ชัน:

var isIOS = (function () {
    var iosQuirkPresent = function () {
        var audio = new Audio();

        audio.volume = 0.5;
        return audio.volume === 1;   // volume cannot be changed from "1" on iOS 12 and below
    };

    var isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent);
    var isAppleDevice = navigator.userAgent.includes('Macintosh');
    var isTouchScreen = navigator.maxTouchPoints >= 1;   // true for iOS 13 (and hopefully beyond)

    return isIOS || (isAppleDevice && (isTouchScreen || iosQuirkPresent()));
})();

โปรดทราบว่าข้อมูลโค้ดนี้เขียนขึ้นโดยให้ความสำคัญกับความสามารถในการอ่านไม่ใช่ความรัดกุมหรือประสิทธิภาพ

คำอธิบาย:

  • หากตัวแทนผู้ใช้มี "iPod | iPhone | iPad" ใด ๆ แสดงว่าอุปกรณ์นั้นเป็น iOS มิฉะนั้นดำเนินการต่อ ...

  • ตัวแทนผู้ใช้อื่น ๆ ที่ไม่มี "Macintosh" ไม่ใช่อุปกรณ์ Apple และไม่สามารถเป็น iOS ได้ ไม่เช่นนั้นเป็นอุปกรณ์ Apple ดังนั้นดำเนินการต่อ ...

  • หากmaxTouchPointsมีค่า1หรือมากกว่านั้นอุปกรณ์ Apple จะมีหน้าจอสัมผัสและต้องเป็น iOS เนื่องจากไม่มี Mac ที่มีหน้าจอสัมผัส (รุ่งโรจน์ถึง kikiwora เพื่อกล่าวถึงmaxTouchPoints) ทราบว่าmaxTouchPointsเป็นundefinedสำหรับ iOS ต่ำกว่า 12 ปีดังนั้นเราจึงต้องแก้ปัญหาที่แตกต่างกันสำหรับสถานการณ์สมมติว่า ...

  • iOS 12 และต่ำกว่ามีมุมแหลมที่ไม่มีอยู่ใน Mac OS สิ่งที่volumeแปลกประหลาดคือคุณสมบัติของAudioองค์ประกอบไม่สามารถตั้งค่าเป็นค่าอื่น1ได้ นี่เป็นเพราะ Apple ไม่อนุญาตการเปลี่ยนแปลงระดับเสียงของAudioองค์ประกอบสำหรับอุปกรณ์ iOS แต่ทำขึ้นสำหรับ Mac OS การเล่นโวหารนั้นสามารถใช้เป็นวิธีสำรองทางเลือกสุดท้ายสำหรับการแยกอุปกรณ์ iOS ออกจากอุปกรณ์ Mac OS



-1

ในกรณีของฉันตัวแทนผู้ใช้ไม่ดีพอเนื่องจากใน Ipad ตัวแทนผู้ใช้เหมือนกับใน Mac OS ดังนั้นฉันต้องทำเคล็ดลับที่น่ารังเกียจ:

var mql = window.matchMedia("(orientation: landscape)");

/**
 * If we are in landscape but the height is bigger than width
 */
if(mql.matches && window.screen.height > window.screen.width) {
    // IOS
} else {
    // Mac OS
}

แค่อ่านคำถามที่บอกว่าตรวจจับ iOS ไม่พบมือถือ
Cybersupernova

-2

ในการตรวจสอบเวอร์ชัน iOS หนึ่งจะต้องปรับโครงสร้างตัวแทนผู้ใช้ด้วยรหัส Javascript ดังนี้:

 var res = navigator.userAgent.match(/; CPU.*OS (\d_\d)/);
    if(res) {
        var strVer = res[res.length-1];
        strVer = strVer.replace("_", ".");
        version = strVer * 1;
    }

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.