Как определить, на какой версии iPhone работает код javascript?

нужно различать между iPhone3x и iPhone4x. Есть ли способ выяснить версию JavaScript, пожалуйста?

7 ответов


можно использовать navigator.userAgent чтобы проверить версию ОС, но это не проблема здесь.

что вы можете сделать, это использовать медиа-запросы, чтобы проверить фактическое разрешение экрана устройства, что может быть причиной проблемы.

var isRetina = window.matchMedia("(-webkit-min-device-pixel-ratio: 2)").matches;

вы также можете обойтись без JavaScript, используя медиа-запросы для загрузки различных таблиц стилей для дисплеев retina:

<link rel="stylesheet" href="retina.css"
    media="only screen and (-webkit-min-device-pixel-ratio: 2)" />

это будет комбинация двух методов в Javascript:

function iPhoneVersion() {
  var iHeight = window.screen.height;
  var iWidth = window.screen.width;
  if (iWidth === 320 && iHeight === 480) {
    return "4";
  }
  else if (iWidth === 375 && iHeight === 667) {
    return "6";
  }
  else if (iWidth === 414 && iHeight === 736) {
    return "6+";
  }
  else if (iWidth === 320 && iHeight === 568) {
    return "5";
  }
  else if (iHeight <= 480) {
    return "2-3";
  }
  return 'none';
}

function isIphone() {
  return !!navigator.userAgent.match(/iPhone/i);
}

поэтому все, что вам нужно сделать, это проверить, если это iPhone, а затем получить версию:

if ( isIphone() && iPhoneVersion() === "6"){
  //code..
}

С помощью расширения WEBGL_debug_renderer_info, которое является частью WebGL API, вы можете получить поставщика GPU и имя визуализатора.

совмещая это с размерами экрана устройства вы можете точно определить, какая версия это. В приведенном ниже примере кода показано, как это можно сделать для всех версий iPhone, включая 3 и 4.

    // iPhone model checks.
function getiPhoneModel() {
    // Create a canvas element which can be used to retrieve information about the GPU.
    var canvas = document.createElement("canvas");
    if (canvas) {
        var context = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
        if (context) {
            var info = context.getExtension("WEBGL_debug_renderer_info");
            if (info) {
                var renderer = context.getParameter(info.UNMASKED_RENDERER_WEBGL);
            }
        }
    }

    // iPhone X
    if ((window.screen.height / window.screen.width == 812 / 375) && (window.devicePixelRatio == 3)) {
        return "iPhone X";
    // iPhone 6+/6s+/7+ and 8+
    } else if ((window.screen.height / window.screen.width == 736 / 414) && (window.devicePixelRatio == 3)) {
        switch (renderer) {
            default:
                return "iPhone 6 Plus, 6s Plus, 7 Plus or 8 Plus";
            case "Apple A8 GPU":
                return "iPhone 6 Plus";
            case "Apple A9 GPU":
                return "iPhone 6s Plus";
            case "Apple A10 GPU":
                return "iPhone 7 Plus";
            case "Apple A11 GPU":
                return "iPhone 8 Plus";
        }
    // iPhone 6+/6s+/7+ and 8+ in zoom mode
    } else if ((window.screen.height / window.screen.width == 667 / 375) && (window.devicePixelRatio == 3)) {
        switch(renderer) {
            default:
                return "iPhone 6 Plus, 6s Plus, 7 Plus or 8 Plus (display zoom)";
            case "Apple A8 GPU":
                return "iPhone 6 Plus (display zoom)";
            case "Apple A9 GPU":
                return "iPhone 6s Plus (display zoom)";
            case "Apple A10 GPU":
                return "iPhone 7 Plus (display zoom)";
            case "Apple A11 GPU":
                return "iPhone 8 Plus (display zoom)";
        }
    // iPhone 6/6s/7 and 8
    } else if ((window.screen.height / window.screen.width == 667 / 375) && (window.devicePixelRatio == 2)) {
        switch(renderer) {
            default:
                return "iPhone 6, 6s, 7 or 8";
            case "Apple A8 GPU":
                return "iPhone 6";
            case "Apple A9 GPU":
                return "iPhone 6s";
            case "Apple A10 GPU":
                return "iPhone 7";
            case "Apple A11 GPU":
                return "iPhone 8";
        }
    // iPhone 5/5C/5s/SE or 6/6s/7 and 8 in zoom mode
    } else if ((window.screen.height / window.screen.width == 1.775) && (window.devicePixelRatio == 2)) {
        switch(renderer) {
            default:
                return "iPhone 5, 5C, 5S, SE or 6, 6s, 7 and 8 (display zoom)";
            case "PowerVR SGX 543":
                return "iPhone 5 or 5c";
            case "Apple A7 GPU":
                return "iPhone 5s";
            case "Apple A8 GPU":
                return "iPhone 6 (display zoom)";
            case "Apple A9 GPU":
                return "iPhone SE or 6s (display zoom)";
            case "Apple A10 GPU":
                return "iPhone 7 (display zoom)";
            case "Apple A11 GPU":
                return "iPhone 8 (display zoom)";
        }
    // iPhone 4/4s
    } else if ((window.screen.height / window.screen.width == 1.5) && (window.devicePixelRatio == 2)) {
        switch(renderer) {
            default:
                return "iPhone 4 or 4s";
            case "PowerVR SGX 535":
                return "iPhone 4";
            case "PowerVR SGX 543":
                return "iPhone 4s";
        }
    // iPhone 1/3G/3GS
    } else if ((window.screen.height / window.screen.width == 1.5) && (window.devicePixelRatio == 1)) {
        switch(renderer) {
            default:
                return "iPhone 1, 3G or 3GS";
            case "ALP0298C05":
                return "iPhone 3GS";
            case "S5L8900":
                return "iPhone 1, 3G";
        }
    } else {
        return "Not an iPhone";
    }
}

я столкнулся с аналогичной проблемой некоторое время назад. Работая на веб-сайте клиента, на котором было много видео, загруженных через javascript, я узнал, что формат видео, который им нужно было использовать, имел странную частоту кадров, которая не работала на iPhone 3GS -.

следуя подходу аторнблада, я добрался до этого решения, которое идеально подходило тому, что мне нужно:

if((navigator.userAgent.match(/iPhone/i)) || (navigator.userAgent.match(/iPod/i))) {
    if (!(window.devicePixelRatio > 1)){
        //non retina iphone / ipod
    }
};

сначала он проверяет, если пользователь приходит ко мне с iPod или iPhone. Затем он проверяет поддержку сетчатки. Поскольку только iPhone 4 + поддерживает его, мне удалось вызвать правильные видеофайлы для старых устройств.


Что-то о более CPU-speed measuring-methods: они могут быть "непригодным" подходом здесь, но выяснение вычислительной мощности вашего целевого устройства может быть полезно для некоторых случаев.

Итак, вот что я хочу добавить к этим методам: вместо подсчета фиксированного значения и измерения времени было бы более надежным подсчитывать фиксированное время, а затем сравнивать достигнутые значения. Если ваш пользователь посещает вас на устройстве, которое намного медленнее, возможно, потому, что оно работает внутри эмулятор, ему придется подождать, пока вы посчитаете до n. если бы вы покинули цикл после, скажем, 200 мс, вы бы просто отреагировали на очень низкое значение, и UX не повлиял.

кроме того, всегда приятно знать, сколько времени займет операция, это уменьшает неопределенности.


возможно, вы можете проверить это, взяв версию ОС в query navigator.appVersion.indexOf("... iphone3G имеет Apple iOS 4.2.1 iphone4 и 4S имеют Apple iOS 5.0.1, но iphone3GS имеет то же самое.

как вариант вы можете обеспечить тест скорости процессора, используя большой цикл. Что-то вроде for (var i=0, k=1; i<5000000; i++) k++; и проверка потребовала времени для этого.

iphone3G (S) имеет максимум 600 МГц, а iphone4-1 ГГц. Итак, есть различие, и вы можете поймать его после некоторых тестов (loop) и определить скорость цикла для каждого iphone поколение.

но обратите внимание, все эти способы являются грубыми и, возможно, не были правильными в других условиях.


решение на самом деле довольно простой, но дольше писать, чем я ожидал.

Как сказал Ян Пак, единственный способ проверить это-проверить скорость процессора. Я написал небольшой цикл, который работает от 0 до 10000000, а затем начал запускать его на разных устройствах. я проверил время до, Чем проверил время после и, конечно, каждое устройство повторило другой результат.

от агента, мы можем знать тип устройства. осталось только разделить скорости. эти это устройства, которые я проверял.

iphone 4s < 200
iphone 4 <300
iphone 3gs <400

ipad 2 <200
all the rest are ipad 1

вот мой код, надеюсь, он поможет кому-нибудь:

var date1 = new Date();//time we started              
for (var i=0, j=1; i<10000000; i++) j++; 
var date2 = new Date();//time we ended
diff=date2.getTime() - date1.getTime(); //time difference.
alert(diff);//show me the difference so i can add lines to more phone types
if (device=='iPad' && diff<200){
    deviceVersion='2';
}
else if (device=='iPad'){
    deviceVersion='1';
}
else if (device=='iphone' && diff<200){
    deviceVersion='4s';
}
else if (device=='iphone' && diff<300){
    deviceVersion='4';
}
else if (device=='iphone' && diff<400){
    deviceVersion='3gs';
}
...

некоторые люди могут предпочесть случай переключателя. мне нравится, если.