Blog. Just Blog

Нестандартный способ определения браузера Internet Explorer

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Web-мастеру и не только | Автор: ManHunter
Начиная с версии 1.2 в языке JavaScript есть интересный метод работы с функциями - arguments.callee. Откроем почитать документацию.


arguments.callee
Специфицирует тело исполняемой в данный момент функции. Свойство callee доступно только в теле функции. Ключевое слово this не относится к исполняемой в данный момент функции. Используйте свойство callee для обращения к функции в теле этой функции.


Проще говоря, результатом выполнения arguments.callee внутри какой-нибудь функции будет тело этой функции. Для наглядного примера код:
  1. function myFunc() {
  2.   return arguments.callee;
  3. }
  4. alert(myFunc());
покажет в MessageBox'е следующее:

Результат arguments.callee
Результат arguments.callee

то есть в точности код вызванной функции. "Ага!" - подумали суровые уральские мужики. - "А если мы поместим в тело функции что-нибудь еще, например железный лом комментарий?" Подумали и поместили.
  1. function myFunc() {
  2.   // Today is a good day to die
  3.   return arguments.callee;
  4. }
  5. alert(myFunc());
Тестирование приведенного кода в разных браузерах показало очень интересный результат. Mozilla Firefox, Safari, K-Meleon, Netscape Navigator и Opera до версии 9.5 показывают код функции БЕЗ комментариев, а Internet Explorer версий 6-7 и Opera 9.5 и выше добросовестно показывают полный текст функции со всеми комментариями. А не попробовать ли нам использовать это поведение браузеров для определения их типов? В результате недолгих раздумий появилась следующая функция:
  1. function detect_ie() {
  2.   function smart_ie_check() {
  3.     // 66 - Internet Explorer Trap
  4.     return(arguments.callee.toString().replace(/[^6]/g,''));
  5.   }
  6.   return(smart_ie_check()=='666' && typeof(opera)!='object');
  7. }
Вложенная функция smart_ie_check() возвращает свое тело, из которого вырезаны все символы, не являющиеся цифрой "6". Напомню, что в Internet Explorer в обрабатываемую строку попадает и комментарий. Результатом работы smart_ie_check() будет "666" для IE-based браузеров и Opera 9.5+, а для всех остальных браузеров вернется "6". Откуда взялись эти "шестерки"? Две из комментария и одна из фильтра replace, итого три. Остается отфильтровать из результатов Opera, для этого проверим тип объекта "opera". В браузерах семейства Opera этот объект является внутренним и определен собственно как "object", в других браузерах вернется "undefined". После всех проверок функция detect_ie() вернет true, если браузер Internet Explorer или IE-based и false для всех остальных браузеров.
Разумеется, полагаться только на эту проверку при определении типа браузера нежелательно, она должна быть использована только как часть комплексной проверки. Но все-таки такая проверка гораздо надежнее чем поиск строки "MSIE" в navigator.userAgent, потому что существует множество программ и плагинов для "камуфляжа" браузеров под совершенно другие.

Поделиться ссылкой ВКонтакте Поделиться ссылкой на Facebook Поделиться ссылкой на LiveJournal Поделиться ссылкой в Мой Круг Добавить в Мой мир Добавить на ЛиРу (Liveinternet) Добавить в закладки Memori Добавить в закладки Google
Просмотров: 5121 | Комментариев: 5

Внимание! Статья опубликована больше года назад, информация могла устареть!

Комментарии

Отзывы посетителей сайта о статье
Isaev (02.04.2012 в 14:37):
Интересно конечно, но завтра любой из этих браузеров добавит поддержку этой функции для совместимости с другими браузерами и будет куча недовольных клиентов у которых скривились фейсы страниц... Вообще конечно люди сами себе проблеммы создают. Почему нельзя сделать стандартную функцию в каждом браузере тип GetBrowserName/Version и не париться с вечной проблеммой детекта? Ведь чем сложнее определить "твой" браузер, тем меньше сайтов будут в нём корректно отображаться и народ будет активно искать альтернативу!
Денис (02.01.2012 в 03:58):
Долее надежным подходом, и хорошим тоном считается проверять не браузер, а конкретную фичу. Например, при установке обработчиков: проверяем наличие функции addEventListener, если она есть используем ее, если нет -- проверяем attachEvent, если есть -- используем, и т.д. Иногда можно делать набор фич, примерно так:
document.implementation.hasFeature("Events", "2.0")

То, что делаете вы, фактически юз недокументированных особенностей. Это может быть оправданно (и романтичненько так) при написании под вин, поскольку время жизни средней проги редко больше жизни версии конкретной винды. И более того, майкрософт, как правило, переносит их все в следующую версию, так как заботится о переносимости. В браузерном же javascript все совсем не так. Версии w3c-совместимых браузеров меняются очень часто, и та недокументированная фича, что работает сегодня, может оказаться несоответствием стандартам (либо не нее нет стандарта, но появится завтра), будет расценена как баг и, соответственно, пофикшена.
А на то что ее кто-то там юзает, и бровью не поведут, в сегодняшнем вебе другие ориентиры.

Сорри, очепятки: "Более надежным подходом", "Иногда можно проверять набор фич," :)
ManHunter (29.01.2009 в 13:52):
Вот еще интересные способы детекта некоторых браузеров
http://www.thespanner.co.uk/20...cript-hacks/
ManHunter (05.10.2008 в 14:04):
Да, кстати, тут попробовал новый гугловский Chrome, там тоже возвращает '666'. Буду подумать что-нибудь против него :)
Nutscracker (04.10.2008 в 21:31):
Еще можно проверять наличие arguments.callee.caller ( http://developer.mozilla.org/E...ction:caller ) – если не ошибаюсь (специально никогда не проверял), данная штука есть только в IE и gecko-based браузерах. А последние можно выловить по наличию Object.prototype.toSource ( http://developer.mozilla.org/e...ect/toSource ) или window.uneval (почему-то как-то вяло с описанием).

P.S. 666 порадовало :)

P.P.S. Кабы не упоминание на форуме – так бы и не посмотрел на баннерокрутилку (что не срезал фильтр, игнорирует мозг :)).

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2018
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.07 сек. / MySQL: 2 (0.0027 сек.) / Память: 4.75 Mb
Наверх