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 缩图函数 (onDOMLoaded)……
Oct 23 Javascript
JavaScript的setAttribute兼容性问题解决方法
Nov 11 Javascript
jquery 获取dom固定元素 添加样式的简单实例
Feb 04 Javascript
js调用浏览器打印模块实现点击按钮触发自定义函数
Mar 21 Javascript
javascript中scrollTop详解
Apr 13 Javascript
简介JavaScript中Boolean.toSource()方法的使用
Jun 05 Javascript
drag-and-drop实现图片浏览器预览
Aug 06 Javascript
学习Javascript面向对象编程之封装
Feb 23 Javascript
Bootstrap模态框案例解析
Mar 05 Javascript
基于Vue实现tab栏切换内容不断实时刷新数据功能
Apr 13 Javascript
Node.js学习之查询字符串解析querystring详解
Sep 28 Javascript
十分钟带你快速了解React16新特性
Nov 10 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 echo()和print()、require()和include()函数区别说明
2010/03/27 PHP
Laravel 5框架学习之表单验证
2015/04/08 PHP
php自定义函数实现二维数组排序功能
2016/07/20 PHP
PHP pthreads v3下worker和pool的使用方法示例
2020/02/21 PHP
细说javascript函数从函数的构成开始
2013/08/29 Javascript
关于jquery中全局函数each使用介绍
2013/12/10 Javascript
使用jquery实现以post打开新窗口
2014/03/19 Javascript
javascript 3d 逐侦产品展示(核心精简)
2014/03/26 Javascript
JavaScript中实现继承的三种方式和实例
2015/01/29 Javascript
浅谈angularjs module返回对象的坑(推荐)
2016/10/21 Javascript
基于javascript实现按圆形排列DIV元素(三)
2016/12/02 Javascript
JS生成和下载二维码的代码
2016/12/07 Javascript
Bootstrap 模态框(Modal)插件代码解析
2016/12/21 Javascript
谈谈第三方App接入微信登录 解读
2016/12/27 Javascript
vue.js树形组件之删除双击增加分支实例代码
2017/02/28 Javascript
vue组件如何被其他项目引用
2017/04/13 Javascript
JS实现带动画的回到顶部效果
2017/12/28 Javascript
完美解决axios在ie下的兼容性问题
2018/03/05 Javascript
vue插件开发之使用pdf.js实现手机端在线预览pdf文档的方法
2018/07/12 Javascript
jQuery中DOM常见操作实例小结
2019/08/01 jQuery
vue项目启动出现cannot GET /服务错误的解决方法
2020/04/26 Javascript
绘制微信小程序验证码功能的实例代码
2021/01/05 Javascript
Vue单页面应用中实现Markdown渲染
2021/02/14 Vue.js
python生成随机图形验证码详解
2017/11/08 Python
python调用接口的4种方式代码实例
2019/11/19 Python
Python TCPServer 多线程多客户端通信的实现
2019/12/31 Python
Python实现列表中非负数保留,负数转化为指定的数值方式
2020/06/04 Python
HTML5网页音乐播放器的示例代码
2017/11/09 HTML / CSS
AmazeUI导航的示例代码
2020/08/14 HTML / CSS
十一国庆节“向国旗敬礼”主题班会活动方案
2014/09/27 职场文书
2014年“向国旗敬礼”网上签名寄语活动方案
2014/09/27 职场文书
民主生活会剖析材料
2014/09/30 职场文书
设立有限责任公司出资协议书
2014/11/01 职场文书
2015年法律事务部工作总结
2015/07/27 职场文书
《桂花雨》教学反思
2016/02/19 职场文书
Django项目如何获得SSL证书与配置HTTPS
2021/04/30 Python