16 марта 2012 в 10:24

Распознаём retina-дисплеи джаваскриптом перевод tutorial

Я отыскивал способ выяснить DPI устройства для употребления в мобильном дизайне. Я ещё не обнаружил его, зато нашёл приём для выяснения того, пользуется ли читатель сайта сетчаточным дисплеем. Вот как без хлопот достичь этого:
var retina = window.devicePixelRatio > 1 ? true : false;

Теперь переменная retina примет значение true, если у читателя сетчаточный дисплей. В дальнейшем можно использовать простой оператор if, чтобы выполнить тот или иной код в зависимости от типа дисплея.

if (retina) {
    // у читателя дисплей типа retina
}
else {
    // у читателя дисплей не типа retina
}

Зачем?

Вот хороший пример: если у меня на сайте иллюстрация (или видео) размером 100×100, то вышеприведённый код посоветует мне скачать иллюстрацию повышенного размера (200×200), чтобы она выглядела чётко на iPhone 4 — а пользователям других устройств не придётся скачивать картинку 200×200 без нужды. Ведь скорость особенно важна для мобильных пользователей.

if (retina) {
    var html = '<img src="200x200.jpg" width=100 height=100>';
} else {
    var html = '<img src="100x100.jpg" width=100 height=100>';
}
Перевод: Brian Cray
Mithgol the Webmaster @Mithgol
карма
66,5
рейтинг 0,0
вебмастер, фидошник
Похожие публикации
Самое читаемое Разработка

Комментарии (31)

  • +3
    При переводе я позволил себе отредактировать последний из примеров кода, потому что в первоисточнике не слишком-то понятно, о чём речь. Вообще же рекомендую заинтересованным читателям рассматривать этот перевод как практический рецепт к теоретической статье Егора Хмелёва «Адаптируем графику под Retina экран» и читать сперва её, хотя Брайан Крэй и опубликовал свою блогозапись куда раньше (5 мая 2011 года). Крэй также не обращает внимания на необходимость проверки существования свойства window.devicePixelRatio, тогда как в действительности она понадобится:

    if (typeof window.devicePixelRatio != 'undefined') {
       if (window.devicePixelRatio > 1) {
          // ретина!
       }
    } 
    
    • 0
      Внимательный читатель наверняка сообразит, что у Хмелёва третий пример ужé включает аналогичную проверку, но только в другой форме:

      if( 'devicePixelRatio' in window && window.devicePixelRatio == 2 ){
         // ретина!
      }
      


      Способ Крэя более пригоден «на вырост» в том смысле, что если развитие техники приведёт к появлению устройств со значением «window.devicePixelRatio == 4», то для них всё равно неплохо бы подзакачать хотя бы удвоенную в размере картинку.
    • +4
      В данном случае проверка не нужна.
      undefined кастуется в NaN в предикатах сравнения, ну и собственно это даёт в результате неизвестное поведение, которое всегда трактуется как false.
      Это по стандарту и не должно быть browser-specific.
      С другой стороны это фишка, и не все могут о ней знать, поэтому можно например воткнуть комментарий.
      • +6
        Но в данном случае я сомневаюсь, что автор знал об этом, так как использует абсолютно бессмысленный в данном случае тернарный оператор сравнения. Бессмысленный потому что предикаты сравнения всегда возвращают boolean.
      • –1
        Спасибо за ценный комментарий. Я как-то не был осведомлён об этой небезынтересной особенности джаваскриптовых сравнений чисел с несуществующими полями объектов.
  • 0
    Имхо, можно проще:

    var retina = !!(window.devicePixelRatio-1);
    
    // и вариант с проверкой на undefined
    
    var retina = function(x){ return !!x && !!(x-1); }(window.devicePixelRatio);
    
    • –1
      Как ни странно, проверка на undefined и тут не нужна, потому что в джаваскрипте !!NaN принимает значение false.

      Это и к лучшему, потому что, честное слово, уж лучше вслед за Крэем записать слишком самоочевидную формулировку ««? true: false», нежели опускаться в такие круги ада, как «function(x){ return !!x && !!(x-1); }(window.devicePixelRatio)».
      • +5
        Собсно, в данном конкретном случае, согласен, не обратил внимание и вполне будет достаточно var retina = window.devicePixelRatio > 1;
  • +12
    Простите, а зачем «? true: false»?
    var retina = window.devicePixelRatio > 1;
    • +2
      Да, это наиболее странное место первоисточника; я полагаю, что Крэй поставил булевые константы для наглядности, граничащей с очевидностью.
  • +1
    Теперь переменная retina примет значение true [...]
    «Абалдееть!»©

    В дальнейшем можно использовать простой оператор if, чтобы выполнить тот или иной код в зависимости от типа дисплея.
    По-моему, тут уже наглядность граничит не с очевидностью, а даже не знаю с чем. Может все же стоило немного адаптировать перевод?
  • –2
    Хе-хе-хе. Может быть. Но я решил оставить авторский стиль глубокого разжёвывания.
  • +18
    «Ретиновый дисплей» — недостаточно русский термин. «Сетчатковый экран» звучит куда более мицгольно.
    • 0
      Ваше наблюдение справедливо. Перехожу на употребление словосочетания «сетчаточный дисплей». (Я ничего не имею против термина «дисплей» в значении «экран бытовой цифровой техники».)
      • +3
        Считаю предложение использовать вражеское слово «экран» не совсем уместным и предлагаю в рамках треда в качестве замены использовать слова «казатель», вариант «показчик».
        • +1
          Отображатель!
      • 0
        Может все-таки «сетчатый»? А то слух режет.
        • 0
          «Сетчатый» — от слова «сетка», а «сетчаточный» — от слова «сетчатка» («retina»).
      • НЛО прилетело и опубликовало эту надпись здесь
      • 0
        Производители принтеров достаточно давно используют термин «ретинальный». Из того, что я слышал, мне этот вариант нравится больше всех.
  • 0
    мда… почему бы это не делать на CSS? У нас же могут быть разные стили для разных разрешений.
    Для тех кто использует responsive webdesign это не есть проблема.
    • +1
      Вы предлагаете заменить картинку в элементе «img» посредством CSS? Ну-ну… Посредством CSS можно менять стили, но не разметку.
    • 0
      Иногда случается необходимость адаптировать к сетчаточному дисплею не только оформление, но и движок.

      Вот пример на GitHub.
  • –2
    var html = '<img src="200x200.jpg" width=100 height=100>';

    Смысл качать 200х200, если отображаться будет всё равно 100х100? :)
    • 0
      100 на 100 в браузерных пикселях, а на retina в одном браузерном пикселе — 4 настоящих. Собственно window.devicePixelRatio за информирование о такой ситуации и отвечает.
  • 0
    Чрезвычайно интересно, как сайты, учитывающие подобным образом window.devicePixelRatio и его CSS-аналоги, будут работать в системах, где devicePixelRatio=1.51.
    • 0
      А и такие системы есть? Или хотя бы проектируются?
      • +1
        Хм, ну, мой ноутбук, например, имеет экран со 145 DPI в течение последних примерно пяти лет. А если разделить 145 на 96, получится как раз столько.

        У предыдущего, кстати, было 125 DPI. И значение этой константы, получается, должно было бы быть 1.3. Примерно.
      • +3
        Ради интереса, посмотрел на спеки известных устройств и посчитал, каково бы должно быть для них значение devicePixelRatio, если всё делать по уму (в сторону: впрочем, если всё делать по уму, то в CSS не надо было в своё время привязывать пиксель к дюйму, потому что один кривой костыль для одного кривого дефолта в одной кривой системе вызывает впоследствии, как мы видим, целый костылепромышленный завод):

        Nexus One: 2.65
        Nexus S: 2.43
        Galaxy Nexus: 3.29

        iPhone 3G/3Gs: 1.70
        iPhone 4/4s: 3.40 (и нифига не 4)
        iPad 1/2: 1.38
        «the new iPad»: 2.75 (и ещё дальше от 4, чем iPhone 4)

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