Javascript-форум (https://javascript.ru/forum/)
-   Ваши сайты и скрипты (https://javascript.ru/forum/project/)
-   -   Определение типа браузера и версии, по возможностям браузера/движка (https://javascript.ru/forum/project/24996-opredelenie-tipa-brauzera-i-versii-po-vozmozhnostyam-brauzera-dvizhka.html)

devote 21.01.2012 17:22

Определение типа браузера и версии, по возможностям браузера/движка
 
вот решил сюда отписать решение по определению браузера на основе возможностей браузера или специальных методов свойственных конкретному браузеру/движку

для начала приведу пример как я пытаюсь выяснить тот или иной браузер, путем проверок наличия тех или иных методов:
hasIE = window.eval && eval("/*@cc_on 1;@*/");
hasOpera = !!window.opera;
hasChrome = !!window.chrome;
hasFireFox = !!window.sidebar;
hasSafari = !window.external && !hasOpera;

Как мы видим все логично и понятно. ИЕ имеет возможность компиляцию условных выражений внутри комментариев. Тем самым мы можем точно выяснить принадлежность движка ИЕ.

В опере и хроме есть встроенные объекты позволяющие нам узнать что за браузер мы используем, для оперы определяем наличие объекта window.opera для хрома window.chrome. По сути тоже все логично.

ФайрФокс и Сафари все немного иначе, файрфокс использует движок Gecko и именно в этом движке имеется объект window.sidebar. Который нужен для работы с боковой панелью браузера. Именно наличие этого объекта нам дает возможность выяснить о принадлежности движка Gecko.

Для сафари совсем все немного иначе, мы просто смотрим отсутствие объекта window.external и смотрим не опера ли это. Так как именно эти два браузера не имеют в наличии объекта window.external.

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

Что у меня вышло:
hasIE = window.eval && eval("/*@cc_on 1;@*/") && (/msie (\d+)/i.exec(navigator.userAgent) || [,true])[1];
hasOpera = !!window.opera && window.opera.version && window.opera.version();
hasChrome = !!window.chrome && (/chrome\/([\d\.]+)/i.exec(navigator.userAgent)[1] || true);
hasFireFox = !!window.sidebar && (/firefox\/([\d\.]+)/i.exec(navigator.userAgent)[1] || true);
hasSafari = !window.external && !hasOpera && (/safari\/([\d\.]+)/i.exec(navigator.userAgent)[1] || true);


Здесь все просто,

Опера имеет внутренний метод с помощью которого можно получить номер версии браузера.

Для всех остальных браузеров приходится версию получать из строки UserAgent и в случае неудачи мы будем иметь не строку версии а значение true в переменной если имеем дело с этим браузером.

В заключении хочу сказать, что каждая переменная имеет тип строка, с номером версии данного браузера. И нам достаточно просто выполнить подобное действие в коде что бы работать далее:
if (hasIE && parseInt(hasIE) == 7) {}
Хотя что вы будете делать со значением в переменой это решать вам. Я лишь привел один из примеров.

Это все что у меня пока пришло в голову, так же хотелось бы придумать возможность определения движков и тип браузера (мобильный, настольный и т.д.). Если есть идеи по этому вопросу, буду признателен выслушать их. Так же не против выслушать критику по методам описанным выше.

Всем спасибо!

melky 21.01.2012 17:59

IE < 9. моя любимая проверка. это к слову.
ielt9 = '\v'=='v';

devote 21.01.2012 18:10

Цитата:

Сообщение от melky (Сообщение 151880)
IE < 9. моя любимая проверка. это к слову.
ielt9 = '\v'=='v';

Это баг движка ИЕ, а на багах лучше не ориентироваться. Ну а вообще да, простая возможность.

Gozar 21.01.2012 18:21

Цитата:

Сообщение от melky (Сообщение 151880)
моя любимая проверка.

У меня давно стандартная.

Стараюсь писать код совместимый с браузерами, всеми кроме IE, всегда получалось, кроме Оперы один раз. IE проверяю, когда что-то нужно чтобы работало, а оно не работает в IE. Под него проще писать свой код или не писать ;)

ps: без либ уже не пишу, а там есть и проверка и версии.

devote 21.01.2012 18:28

Цитата:

Сообщение от Gozar
IE проверяю, когда что-то нужно чтобы работало, а оно не работает в IE.

Ну у меня чаще всего что-то не работает дык это в ИЕ7. а в ИЕ8 норм. И подобная конструкция '\v'=='v'; увы не даст мне знать ИЕ7 ли это.

melky 21.01.2012 18:31

Цитата:

Сообщение от devote (Сообщение 151886)
Это баг движка ИЕ, а на багах лучше не ориентироваться. Ну а вообще да, простая возможность.

этот баг уже так долго существует, что перешёл из разряда "багов" в разряд "фич". мне кажется, что и уйдёт он со смертью IE.

devote 21.01.2012 18:35

Цитата:

Сообщение от melky
этот баг уже так долго существует, что перешёл из разряда "багов" в разряд "фич". мне кажется, что и уйдёт он со смертью IE.

Ну это да, если в МС есть баг, то это автоматом не баг а фича. Ибо МС не особо старается их убирать. Так что я согласен, что по отношению к МС это нельзя считать багом :D

Octane 21.01.2012 18:39

А почему это баг? Просто вертикальная табуляция не поддерживается, поэтому v не преобразуется в спец символ. Для других символов тоже верно:
alert("\o" == "o") //true во всех браузерах

devote 21.01.2012 18:45

Цитата:

Сообщение от Octane
Просто вертикальная табуляция не поддерживается

Согласен, беру свои слова обратно о баге.

Но все же никто по теме посоветовать ничего не может?

monolithed 21.01.2012 21:55

Цитата:

Сообщение от devote
Но все же никто по теме посоветовать ничего не может?

Зачем это вообще нужно?
Если хочется найти более корректное или оптимальное решение, то следует посмотреть исходники популярных либ.

devote 21.01.2012 22:08

Цитата:

Сообщение от monolithed
то следует посмотреть исходники популярных либ.

там все по юзерагенту сделано... а мне это не нужно.

monolithed 21.01.2012 22:21

Цитата:

Сообщение от devote
там все по юзерагенту сделано... а мне это не нужно.

А смысл извращаться?

float 21.01.2012 22:30

Цитата:

Но все же никто по теме посоветовать ничего не может?
Цитата:

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

devote 21.01.2012 22:47

Цитата:

Сообщение от float
то я бы не стал надеяться на глобальные переменные...

тоесть на строку UserAgent у вас больше надежды нежели на реальные возможности?

melky 21.01.2012 22:48

Цитата:

Сообщение от devote (Сообщение 151946)
тоесть на строку UserAgent у вас больше надежды нежели на реальные возможности?

userAgent можно подменить, а вот баги фичи браузеров - никак. может, стоит ориентироваться только на них?

devote 21.01.2012 22:52

Цитата:

Сообщение от melky
может, стоит ориентироваться только на них?

Ну дык я это и пытаюсь сделать.

melky 21.01.2012 22:56

Цитата:

Сообщение от devote (Сообщение 151950)
Ну дык я это и пытаюсь сделать.

наверное, это может вам помочь. правда, остаётся только определить версию. Но ведь это уже можно сделать с помощью user-agent (кроме IE, там слишком большие различия)?

PS. можно так же проверить версию браузера через реализацию каких-нибудь фич, вроде css animations.

Kolyaj 21.01.2012 22:57

devote,
у вас очень популярное заблуждение: вы, наверное, думаете, что это вы feature detection сделали. Нет, это не feature detection, это browser detection. Это чуть лучше, чем проверка userAgent, но лучше только тем, что userAgent можно подменить.

Feature detection -- это когда проверяется наличие конкретной фичи перед тем, как использовать эту фичу.

Например.
// feature detection
if (window.addEventListener) {
    window.addEventListener(...);
} else if (window.attachEvent) {
    window.attachEvent(...);
}


// не feature detection
if ('\v' == 'v') {
    window.attachEvent(...);
} else {
    window.addEventListener(...);
}



Есть фичи, наличие которых проверить нельзя. Как правило это различные баги браузеров. Тогда остаётся только browser detection. Неважно какой, они все плохие. Хотя проверка специфических переменных лучше, чем userAgent.

trikadin 21.01.2012 23:08

Kolyaj, нет, речь идёт не об определении возможностей браузера, а об определении браузера и версии браузера по наличию в них каких-то фич.

Kolyaj 21.01.2012 23:12

Цитата:

Сообщение от trikadin
об определении браузера и версии браузера по наличию в них каких-то фич.

Для чего это будет использоваться?

monolithed 21.01.2012 23:17

devote,
Features

devote 21.01.2012 23:23

Цитата:

Сообщение от monolithed (Сообщение 151967)
devote,
Features

Понятия не имею к чему это, или вы думаете что к примеру объект window.opera или window.chrome исчезнут не в далеком будущем?

monolithed 21.01.2012 23:33

Цитата:

Сообщение от devote
Понятия не имею к чему это

По этой ссылке собран список наиболее популярных feature/bag detections.
Цитата:

Сообщение от devote
или вы думаете что объект window.opera или window.chrome исчезнут не в далеком будущем

Ну во-первых их можно переопределить, во-вторых не исключено что потом исчезнут.
Если вы хотите сделать определение браузера в виде универсальной бибилиотеки, то используйте userAgent как это делают все, если же вам нужно сделать библиотеку, которая будет служить основой для определения feature, то посмотрите как это сделано в has.js

devote 21.01.2012 23:39

Цитата:

Сообщение от monolithed
то посмотрите как это сделано в has.js

не вижу ничего общего с определением типа браузера/движка с определением того или иного метода.

monolithed 22.01.2012 00:03

Если делать универсальное решение, с IE и Opera думаю вполне решаемая задача, а вот для других браузеров без использрвания userAgent не обойтись, т.к. FF за свое существование менял несколько раз движок, в WebKit тоже не все гладко, постоянно что-то добавляют/удаляют

devote 22.01.2012 00:06

Цитата:

Сообщение от monolithed
т.к. FF за свое существование менял несколько раз движок, в WebKit тоже не все гладко, постоянно что-то добавляют/удаляют

Вот поэтому я и поднял тему.. так как именно с этими браузерами не все идеально.

monolithed 22.01.2012 00:27

Можно установить все предыдущие билды и составить матрицу, однако нет никакой уверенности в том, что в следующем поколении не вылезут старые особенности.
Для этой цели придется брать за основу bag detections и особенности движков (лучше смотреть исходники, если доступны), затем проверять feature detections на случай если всплыли старые баги в новом билде и опцинально userAgent. Вобщем работа не простая.


Часовой пояс GMT +3, время: 20:05.