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 相关文章推荐
bcastr2.0 通用的图片浏览器
Nov 22 Javascript
jquery 回车事件实现代码
Aug 23 Javascript
js 处理数组重复元素示例代码
Dec 27 Javascript
JavaScript实现的石头剪刀布游戏源码分享
Aug 22 Javascript
js实现网页标题栏闪烁提示效果实例分析
Nov 20 Javascript
js上传图片及预览功能实例分析
Apr 24 Javascript
jquery实现标签上移、下移、置顶
Apr 26 Javascript
在Javascript中处理数组之toSource()方法的使用
Jun 09 Javascript
JavaScript直播评论发弹幕切图功能点集合效果代码
Jun 26 Javascript
angular2组件中定时刷新并清除定时器的实例讲解
Aug 31 Javascript
详解如何webpack使用DllPlugin
Sep 30 Javascript
vue实现购物车结算功能
Jun 18 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实现单例模式建立数据库连接的方法分析
2020/02/11 PHP
JS中style属性
2006/10/11 Javascript
关于实现代码语法标亮 dp.SyntaxHighlighter
2007/02/02 Javascript
jquery+json实现数据列表分页示例代码
2013/11/15 Javascript
Jquery原生态实现表格header头随滚动条滚动而滚动
2014/03/18 Javascript
JS上传图片前实现图片预览效果的方法
2015/03/02 Javascript
浅谈JavaScript中的Math.atan()方法的使用
2015/06/14 Javascript
JS实现仿腾讯微博无刷新删除微博效果代码
2015/10/16 Javascript
JavaScript组合模式学习要点
2016/08/26 Javascript
JS 动态判断PC和手机浏览器实现代码
2016/09/21 Javascript
Bootstrap媒体对象学习使用
2017/03/07 Javascript
基于JS脚本语言的基础语法详解
2017/07/22 Javascript
vue进行图片的预加载watch用法实例讲解
2018/02/07 Javascript
Vue-cli项目获取本地json文件数据的实例
2018/03/07 Javascript
修改node.js默认的npm安装目录实例
2018/05/15 Javascript
vue轻量级框架无法获取到vue对象解决方法
2019/05/12 Javascript
浅谈一种让小程序支持JSX语法的新思路
2019/06/16 Javascript
mpvue 页面预加载新增preLoad生命周期的两种方式
2019/10/17 Javascript
javascript中的offsetWidth、clientWidth、innerWidth及相关属性方法
2020/05/14 Javascript
html-webpack-plugin修改页面的title的方法
2020/06/18 Javascript
Vue中keep-alive组件的深入理解
2020/08/23 Javascript
[01:06:19]DOTA2-DPC中国联赛定级赛 LBZS vs SAG BO3第二场 1月8日
2021/03/11 DOTA
python查询sqlite数据表的方法
2015/05/08 Python
Python编程中字符串和列表的基本知识讲解
2015/10/14 Python
Python字符串切片操作知识详解
2016/03/28 Python
Python Series从0开始索引的方法
2018/11/06 Python
Python 函数返回值的示例代码
2019/03/11 Python
使用Python实现Wake On Lan远程开机功能
2020/01/22 Python
基于Django OneToOneField和ForeignKey的区别详解
2020/03/30 Python
Timex手表官网:美国运动休闲手表品牌
2017/01/28 全球购物
德国滑雪和户外用品网上商店:XSPO
2019/10/30 全球购物
英国运动风奢侈品购物网站:Maison De Fashion
2020/08/28 全球购物
ASP.NET中的身份验证有那些
2012/07/13 面试题
测绘专业大学生职业生涯规划书
2014/02/10 职场文书
2015年端午节活动总结
2015/02/11 职场文书
百年孤独读书笔记
2015/06/29 职场文书