JavaScript编写检测用户所使用的浏览器的代码示例


Posted in Javascript onMay 05, 2016

能力检测
在编写代码之前先检测特定浏览器的能力。例如,脚本在调用某个函数之前,可能要先检测该函数首付存在。这种检测方法将开发人员从考虑具体的浏览器类型和版本中解放出来,让他们把注意力集中到相应的能力是否存在上。能力检测无法精确地检测特定的浏览器和版本。

怪癖检测
怪癖实际上是浏览器实现中存在的bug,例如早期的webkit中就存在一个怪癖,即它会再for-in循环中返回被隐藏的属性。怪癖检测通常涉及到运行一段代码,然后确定浏览器是否存在某个怪癖。由于怪癖检测无法精确地检测特定的浏览器和版本。

用户代理检测
通过检测用户代理字符串来识别浏览器。用户代理字符串中包含大量与浏览器有关的信息,包括浏览器、平台、操作系统及浏览器版本。用户代理字符串有过一段相当长的发展历史,在此期间,浏览器提供商视图通过在用户代理字符串总添加一些欺骗性信息,欺骗网站详细自己的浏览器是另外一种浏览器。用户代理检测需要特殊的技巧,特别是要注意Opera会隐瞒其用户代理字符串的情况。即便如此,通过用户代理字符串仍然能够检测出浏览器所用的呈现引擎以及所在的平台,包括移动设备和游戏系统。

在每一次HTTP请求过程中,用户代理字符串是作为响应首部发送的,而且该字符串可以通过Javascript的navigator.userAgent属性访问。在服务器端,通过检测用户代理字符串来确定用户使用的浏览器是一种常用而且广为接受的做法。而在客户端,用户代理检测一般被当作一种万不得已的做法,其优先级排在能力检测和怪癖检测之后。

var client = function(){
 // 呈现引擎
 var engine = {
  ie:0,
  gecko:0,
  webkit:0,
  khtml:0,
  opera:0,

  // 完整的版本号
  ver:null
 };

 // 浏览器
 var browser = {
  // 主要浏览器
  ie:0,
  firefox:0,
  safari:0,
  konq:0,
  opera:0,
  chrome:0,

  // 具体的版本号
  ver:null
 };

 // 检测呈现引擎和浏览器
 var ua = navigator.userAgent;
 if (window.opera) {
  engine.ver = browser.ver = window.opera.version();
  engine.opera = browser.opera = parseFloat(engine.ver);
 } else if (/AppleWebKit\/(\S+)/.test(ua)) {
  engine.ver = RegExp["$1"];
  engine.webkit = parseFloat(engine.ver);

  // 确定是Chrome还是Safari
  if (/Chrome\/(\S+)/.test(ua)) {
   browser.ver = RegExp["$1"];
   browser.chrome = parseFloat(engine.ver);
  } else if (/Version\/(S+)/.test(ua)) {
   browser.ver = RegExp["$1"];
   browser.safari = parseFloat(browser.ver);
  } else {

   // 近似地确定版本号
   var safariVersion = 1;
   if (engine.Webkit <100) {
    safariVersion = 1;
   } else if (engine.webkit < 312) {
    safariVersion = 1.2;
   } else if (engine.webkit < 412) {
    safariVersion = 1.3;
   } else {
    safariVersion = 2;
   }

   browser.safari = browser.ver = safariVersion;
  }
 } else if (/KHTML\/(S+)/.test(ua) || /Konqueror\/([^;]+)/.test(ua)) {
  engine.ver = browser.ver = RegExp["$1"];
  engine.khtml = browser.kong = parseFloat(engine.ver);
 } else if (/rv:([^\)]+)\) Gecko\/\d{8}/.test(ua)){
  engine.ver = RegExp["$1"];
  engine.gecko = parseFloat(engine.ver);

  // 确定是不是firefox
  if (/Firefox\/(S+)/.test(ua)) {
   browser.ver = RegExp["$1"];
   browser.firefox = parseFloat(browser.ver);
  }
 } else if (/MSIE ([^;]+)/.test(ua)) {
  engine.ver = browser.ver = RegExp["$1"];
  engine.ie = browser.ie = parseFloat(engine.ver);

 }

 // 检测浏览器
 browser.ie = engine.ie;
 browser.opera = engine.opera;

 // 返回这些对象
 return {
  engine:engine,
  browser: browser
 }
}();

console.log(client.engine);
console.log(client.browser);

Tangram 检测浏览器源码

/**
 * 声明baidu包
 */
var baidu = baidu || {version: "1-3-2"}; // meizz 20100513 将 guid 升级成 \x06
baidu.guid = "$BAIDU$";//提出guid,防止修改window[undefined] 20100504 berg

/**
 * meizz 2010/02/04
 * 顶级域名 baidu 有可能被闭包劫持,而需要页面级唯一信息时需要用到下面这个对象
 */

window[baidu.guid] = window[baidu.guid] || {};

/**
 * 声明baidu.browser包
 */
baidu.browser = baidu.browser || {};

/**
 * 判断是否为isGecko
 */
baidu.browser.isGecko = /gecko/i.test(navigator.userAgent) && !/like gecko/i.test(navigator.userAgent);

/**
 * 判断是否为isWebkit
 */
baidu.browser.isWebkit = /webkit/i.test(navigator.userAgent);

/**
 * 判断是否为标准模式
 */
baidu.browser.isStrict = document.compatMode == "CSS1Compat";

/**
 * 判断是否为safari浏览器
 */
if ((/(\d+\.\d)(\.\d)?\s+safari/i.test(navigator.userAgent) && !/chrome/i.test(navigator.userAgent))) {
 baidu.browser.safari = parseFloat(RegExp['\x241']);
}

/**
 * 判断是否为opera浏览器
 */
if (/opera\/(\d+\.\d)/i.test(navigator.userAgent)) {
 baidu.browser.opera = parseFloat(RegExp['\x241']);
}

/**
 * 判断是否为chrome浏览器
 */
if (/chrome\/(\d+\.\d)/i.test(navigator.userAgent)) {
 baidu.browser.chrome = parseFloat(RegExp['\x241']);
}

/**
 * 判断是否为ie浏览器
 */
if (/msie (\d+\.\d)/i.test(navigator.userAgent)) {
 baidu.ie = baidu.browser.ie = document.documentMode || parseFloat(RegExp['\x241']);
}

/**
 * 判断是否为firefox浏览器
 */
if (/firefox\/(\d+\.\d)/i.test(navigator.userAgent)) {
 baidu.browser.firefox = parseFloat(RegExp['\x241']);
 // '\x241' 是八进制表示法 '\x24' 对应字符 '$' ,所以 '\x241' 等同于 '$1'
}
Javascript 相关文章推荐
在JavaScript的jQuery库中操作AJAX的方法讲解
Aug 15 Javascript
数据结构中的各种排序方法小结(JS实现)
Jul 23 Javascript
微信小程序 action-sheet底部菜单详解
Oct 27 Javascript
JavaScript中undefined和null的区别
May 03 Javascript
Vue 自定义动态组件实例详解
Mar 28 Javascript
vue如何在自定义组件中使用v-model
May 14 Javascript
vue input 输入校验字母数字组合且长度小于30的实现代码
May 16 Javascript
详解vue-cli 2.0配置文件(小结)
Jan 14 Javascript
JavaScript数据结构之栈实例用法
Jan 18 Javascript
springboot+vue+对接支付宝接口+二维码扫描支付功能(沙箱环境)
Oct 15 Javascript
js 图片懒加载的实现
Oct 21 Javascript
vue vant中picker组件的使用
Nov 03 Javascript
JS中dom0级事件和dom2级事件的区别介绍
May 05 #Javascript
整理JavaScript对DOM中各种类型的元素的常用操作
May 05 #Javascript
jQuery Mobile 和 Kendo UI 的比较
May 05 #Javascript
深入理解js promise chain
May 05 #Javascript
详解JavaScript中基于原型prototype的继承特性
May 05 #Javascript
5个最顶级jQuery图表类库插件【jquery插件库】
May 05 #Javascript
javaScript中的原型解析【推荐】
May 05 #Javascript
You might like
PHP MySQL应用中使用XOR运算加密算法分享
2011/08/28 PHP
ThinkPHP单字母函数(快捷方法)使用总结
2014/07/23 PHP
PHP字符串word末字符实现大小写互换的方法
2014/11/10 PHP
php简单实现发送带附件的邮件
2015/06/10 PHP
微信公众号支付之坑:调用支付jsapi缺少参数 timeStamp等错误解决方法
2016/01/12 PHP
php实现xml与json之间的相互转换功能实例
2016/07/07 PHP
PHP线程的内存回收问题
2016/07/08 PHP
js遍历td tr等html元素
2012/12/13 Javascript
解析瀑布流布局:JS+绝对定位的实现
2013/05/08 Javascript
原生Js实现元素渐隐/渐现(原理为修改元素的css透明度)
2013/06/24 Javascript
js中的onchange和onpropertychange (onchange无效的解决方法)
2014/03/08 Javascript
jquery分页对象使用示例
2014/04/01 Javascript
jQuery对于显示和隐藏等常用状态的判断方法
2014/12/13 Javascript
node.js中的fs.ftruncate方法使用说明
2014/12/15 Javascript
AngularJS表单编辑提交功能实例
2015/02/13 Javascript
JavaScript实现DIV层拖动及动态增加新层的方法
2015/05/12 Javascript
JQuery boxy插件在IE中边角图片不显示问题的解决
2015/05/20 Javascript
js根据手机客户端浏览器类型,判断跳转官网/手机网站多个实例代码
2016/04/30 Javascript
详解vue-cli中的ESlint配置文件eslintrc.js
2017/09/25 Javascript
vue自定义过滤器创建和使用方法详解
2017/11/06 Javascript
原生JS实现微信通讯录
2020/06/18 Javascript
python调用Moxa PCOMM Lite通过串口Ymodem协议实现发送文件
2014/08/15 Python
python使用正则表达式替换匹配成功的组并输出替换的次数
2017/11/22 Python
运行django项目指定IP和端口的方法
2018/05/14 Python
有关Python的22个编程技巧
2018/08/29 Python
python输入整条数据分割存入数组的方法
2018/11/13 Python
详解Python locals()的陷阱
2019/03/26 Python
pycharm中显示CSS提示的知识点总结
2019/07/29 Python
学习和使用python的13个理由
2019/07/30 Python
Python读取分割压缩TXT文本文件实例
2020/02/14 Python
Pycharm中安装wordcloud等库失败问题及终端通过pip安装的Python库如何添加到Pycharm解释器中(推荐)
2020/05/10 Python
Python中免验证跳转到内容页的实例代码
2020/10/23 Python
就业协议书的作用
2014/04/11 职场文书
六查六看心得体会
2014/10/14 职场文书
旷工辞退通知书
2015/04/17 职场文书
sql时间段切分实现每隔x分钟出一份高速门架车流量
2022/02/28 SQL Server