Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 10.10.2008, 18:19
Отправить личное сообщение для Octane Посмотреть профиль Найти все сообщения от Octane  
Регистрация: 10.07.2008
Сообщений: 3,873

Browser Detection
Давайте попробуем найти самый оптимальный способ определения браузеров :cool:
Рассмотрев несколько примеров из известных фреймворков и основываясь на собственном опыте написал такой код:
var browser = function() {
	var ua = navigator.userAgent, gecko = /Gecko\//.test(ua) ? ua.match(/; rv:1\.(\d+?)\.(\d)/) : 0,
	webkit = /AppleWebKit/.test(ua), safari = webkit && /Safari\//.test(ua),
	ie = 0 /*@cc_on + @_jscript_version * 10 % 10 @*/;
	return {
		ie: ie >= 5 ? ie : 0,
		gecko: gecko ? '1.' + gecko.slice(1).join('.') : 0,
		firefox: gecko ? (gecko[1] == 9 ? 3 : gecko[1] == 8 && gecko[2] > 0 ? 2 : 0) : 0,
		opera: window.opera && opera.version ? opera.version()[0] : 0,
		webkit: webkit ? ua.match(/AppleWebKit\/(\d+?\.\d+?\s)/)[1] : 0,
		safari: safari && /Version\//.test(ua) ? ua.match(/Version\/(\d{1})/)[1] : 0,
		chrome: safari && /Chrome\//.test(ua) ? ua.match(/Chrome\/(\d+?\.\d)/)[1] : 0
	};
}();

Здесь при использовании IE5.01 и ниже атрибут browser.ie будет равен 0, потому что врятле уже кто-то будет писать код для IE5.01 без использования apply.

В результате выполнения этого кода в FF3.0.3 получается вот такой объект:
browser = {
  ie:0,
  gecko:"1.9.0",
  firefox:3,
  opera:0,
  webkit:0,
  safari:0,
  chrome:0
};


Какие у Вас есть предложения по улучшению кода? Может быть кто-то знает более короткие или быстрые способы узнать, какой браузер используется? Какие браузеры стоит добавить в список, а какие убрать? И т.д. и т.п.
Так же будет интересно, если кто-то сможет протестировать код в разных версиях Safari.

Последний раз редактировалось Octane, 14.10.2008 в 19:35.
Ответить с цитированием
  #2 (permalink)  
Старый 11.10.2008, 14:15
...
Отправить личное сообщение для Zeroglif Посмотреть профиль Найти все сообщения от Zeroglif
 
Регистрация: 09.03.2008
Сообщений: 216

Сообщение от Octane
Какие у Вас есть предложения по улучшению кода?
Есть предложение отказаться от такого рода проверки вообще.

Такое "определение браузера/версии" можно назвать условным, без гарантий. Любое изменение строк производителем UA или пользователем, любое изменение особенностей движка может привести к проблемам. Из недавних...

Если пару слов навскидку по скрипту, то вы смешиваете "главные" строки со "второстепенными". Например, если мы нашли 'gecko', но по каким-то причинам не нашли номер версии, то браузер не определится вообще. Или, определив объект 'opera', мы можем не определить 'version', т.к. первый старше второго версий на несколько, браузер снова не определится. Значением 'version' является строка, возможность применить к строке ака массивное обращение '[0]' - это экстеншн, вне рамок стандарта. Определяя IE, можно было бы просто сравнить номер полученной версии с чем-то, не обязательно множить на десять и ловить хвостик. Чем черт не шутит, возможно MS начнёт очень быстро менять версии jscript.dll и в недалёком будущем (IE8+) нам засветит версия 6.0+, ваш скрипт в этом случае споткнётся. И вообще, номер версии jscript не обязательно говорит о версии браузера, 5.7 встречается и на IE<7 (разные либы с одним номером). Ну, и надо как-то размыкать возможную двойственность, к примеру, у меня в Опере что 'browser.gecko=',что 'browser.opera=' выдают номера версий, т.к. Опера представляется фоксом и меня, как пользователя, это совершенно не волнует...
Ответить с цитированием
  #3 (permalink)  
Старый 12.10.2008, 15:47
Отправить личное сообщение для Octane Посмотреть профиль Найти все сообщения от Octane  
Регистрация: 10.07.2008
Сообщений: 3,873

Спасибо за полезные ссылки.
Сообщение от Zeroglif Посмотреть сообщение
Есть предложение отказаться от такого рода проверки вообще.
Да я тоже не сторонник подобных проверок, в своих скриптах стараюсь сводить их к минимуму: IE и другие браузеры. Но всё таки иногда нужно знать какой браузер используется с точностью до версии, например, для исправления некоторых особенностей в вёрстке.

По поводу работы со строкой «userAgent». John Resing к примеру, в своём блоге советует не использовать object detection (if(window.opera) {…}), а определять браузер именно по «userAgent». Поэтому тут спорный момент, является ли изменение пользователем строки «userAgent» его проблемой или программист должен предусмотреть эту возможность?

По поводу определения версии IE — это самый короткий и стабильный способ определения Internet Explorer, известный мне. В Internet Explorer 8 вроде бы уже известно, что версия JScript будет 5.8. Так, что у нас в запасе ещё есть 5.9, а когда JScript дорастет до 6.0 ещё не известно нужен ли будет подобный скрипт вообще, да и то что есть сейчас не трудно исправить.

Постараюсь разобраться в приведённых Вами примерах и улучшить код.
Ответить с цитированием
  #4 (permalink)  
Старый 12.10.2008, 17:32
...
Отправить личное сообщение для Zeroglif Посмотреть профиль Найти все сообщения от Zeroglif
 
Регистрация: 09.03.2008
Сообщений: 216

Сообщение от Octane
John Resing к примеру, в своём блоге советует не использовать object detection (if(window.opera), а определять браузер именно по «userAgent».
Про это речь? Древний, известный большинству специалистов, баг назван им "fantastically difficult to spot and work around", сама ситуация неправильно истолкована, как что-то там про "global variables" да ещё и маловероятный id="opera" там же... нагнал страху. И я там не увидел, чтобы он прямо советовал "user-agent", шифруется евангелистом, хотя либа егоЙная говорит сама за себя... Проблема-то в другом - насколько показателен window.opera с точки зрения задач? Если нужно кинуть алерт: "Привет, юзверь Оперы5+!" или зачем-то отсечь сумасшедших с более старыми версиями - это одно, а если основывать на этом решения, специально заточенные под современную Оперу, то тут будет нужна более продвинутая со всех точек зрения версия (допустим, 7+), и window.opera уже не советчик, просится "feature detection".

Сообщение от Octane
это самый короткий и стабильный способ определения Internet Explorer
Спсособ определения версии jscript, не версии браузера. Я бы очень хотел иметь таблицу с привязками изменений в языке к версиям/билдам jscript-овых либ, но увы, а IE само собой определяется, комменты ж его.

Сообщение от Octane
версия JScript будет 5.8
Планируют. Но с перспективой принятия ES3.1 развитие версий может резко ускориться.

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

Цитата:
Ok, I figured out. CNN.COM video does not like Chrome. It checks the browser by matching navigator.vendor string against 'Apple'. Because we changed navigator.string to 'Google Inc' recently, it does not treat Google Chrome as Safari anymore.

Someone needs to call CNN.com to fix the issue.
http://code.google.com/p/chromium/issues/detail?id=475
Или по тем же причинам уже на games.yahoo.com:

Цитата:
This is Evangelism!!
The line that's causing the issue is g=(n.vendor.indexOf("Ap")==0) ? 3 : (n.productSub>20030623)?2:0; This returns 0 for Chrome and hence not displaying flash content.
http://code.google.com/p/chromium/issues/detail?id=2446
Ответить с цитированием
  #5 (permalink)  
Старый 12.10.2008, 17:48
Отправить личное сообщение для Octane Посмотреть профиль Найти все сообщения от Octane  
Регистрация: 10.07.2008
Сообщений: 3,873

А чем
window.opera.version()
плохо? Может я чего то не знаю :confused:
Ответить с цитированием
  #6 (permalink)  
Старый 12.10.2008, 20:31
Отправить личное сообщение для Андрей Параничев Посмотреть профиль Найти все сообщения от Андрей Параничев
 
Регистрация: 21.02.2008
Сообщений: 1,250

Zeroglif,
Бывают ситуации, где простым object detection не обойтись, например в работе с клавиатурным вводом, где одинаковые свойства в разных браузерах имеют разные значения. Или, например, установка специфических событий, например DOMContentLoaded - просто проверить наличие addEventListener недостаточно.
Ответить с цитированием
  #7 (permalink)  
Старый 12.10.2008, 21:50
...
Отправить личное сообщение для Zeroglif Посмотреть профиль Найти все сообщения от Zeroglif
 
Регистрация: 09.03.2008
Сообщений: 216

Сообщение от Octane
А чем
В вашем скрипте чем плохо? Ничего ужасного, я только сказал о том, что свойство 'opera' для версий >5, а 'opera.version' для >7.6, в промежутке 5-7.6 опера не определится. Заодно из слабовыраженных недостатков 'window.opera' можно назвать возможность удаления этого объекта самим оперистом, до сих пор встречаются такого рода рекомендации (UserJS и проч.) под соусом "пробиться на сайт, который блокирует Оперу, опрашивая это свойство"... Кстати, я сейчас попробовал в 8-ке обращение к символам строки в массивном стиле, не прошло? непонятно, когда они это ввели.

Сообщение от Андрей Параничев
Бывают ситуации, где простым object detection не обойтись
А как вы предполагаете в этих случаях точно определять каждый браузер?

Сообщение от Андрей Параничев
например DOMContentLoaded - просто проверить наличие addEventListener недостаточно
Поясните, пжлста.
Ответить с цитированием
  #8 (permalink)  
Старый 12.10.2008, 22:13
Отправить личное сообщение для Octane Посмотреть профиль Найти все сообщения от Octane  
Регистрация: 10.07.2008
Сообщений: 3,873

Да это я что-то увлекся, работая со строкой, как с массивом символов :-) хотя во всех современных браузерах работает, надо будет переписать через charAt.
Opera ниже версии 7.6 в принципе и не нужна, если Вы не заметили, то в моем скрипте отсекается FireFox 1.x.x. Толку от определения древнейших браузеров в современном скрипте практически никаких, напичканный всякими apply и XMLHttpRequest он в любом случае не заработает в старом браузере.

Не все браузеры поддерживающие addEventListener обрабатывают событие DOMContentLoaded, поэтому в этом случае object detection бессилен.
Ответить с цитированием
  #9 (permalink)  
Старый 14.10.2008, 15:19
...
Отправить личное сообщение для Zeroglif Посмотреть профиль Найти все сообщения от Zeroglif
 
Регистрация: 09.03.2008
Сообщений: 216

Сообщение от Octane
Opera ниже версии 7.6 в принципе и не нужна, если Вы не заметили, то в моем скрипте отсекается FireFox 1.x.x.
Ну, я как-то не связал Op с FF в смысле общего настроя на современные браузеры, IE6 намного древнее обоих, но отбрасывать его за это (за старость) мало кто отваживается, btw предположу, что вы опечатались в регулярном, оставив метасимвол вместо точки после единички.
Ответить с цитированием
  #10 (permalink)  
Старый 14.10.2008, 19:34
Отправить личное сообщение для Octane Посмотреть профиль Найти все сообщения от Octane  
Регистрация: 10.07.2008
Сообщений: 3,873

Сообщение от Zeroglif Посмотреть сообщение
вы опечатались в регулярном, оставив метасимвол вместо точки после единички.
Спасибо, поправил.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск