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 相关文章推荐
JQuery 解析多维的Json数据格式
Nov 02 Javascript
7个jQuery最佳实践
Jan 12 Javascript
实例解析jQuery中如何取消后续执行内容
Dec 01 Javascript
angular分页指令操作
Jan 09 Javascript
详解利用jsx写vue组件的方法示例
Jul 17 Javascript
Ionic学习日记实现验证码倒计时
Feb 08 Javascript
用Object.prototype.toString.call(obj)检测对象类型原因分析
Oct 11 Javascript
微信小程序前端自定义分享的实现方法
Jun 13 Javascript
no-vnc和node.js实现web远程桌面的完整步骤
Aug 11 Javascript
layui问题之渲染数据表格时,仅出现10条数据的解决方法
Sep 12 Javascript
layui实现下拉复选功能的例子(包括数据的回显与上传)
Sep 24 Javascript
Vue基于localStorage存储信息代码实例
Nov 16 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编写一个简单的路由类
2011/04/13 PHP
浅析echo(),print(),print_r(),return之间的区别
2013/11/27 PHP
yii2.0使用Plupload实现带缩放功能的多图上传
2015/12/22 PHP
老司机传授Ubuntu下Apache+PHP+MySQL环境搭建攻略
2016/03/20 PHP
PHP jpgraph库的配置及生成统计图表:折线图、柱状图、饼状图
2017/05/15 PHP
Js基础学习资料
2010/11/23 Javascript
js 判断checkbox是否选中的操作方法
2012/11/09 Javascript
jquery的选择器的使用技巧之如何选择input框
2013/09/22 Javascript
javascript中的if语句使用介绍
2013/11/20 Javascript
深入理解JavaScript是如何实现继承的
2013/12/12 Javascript
同域jQuery(跨)iframe操作DOM(示例代码)
2013/12/13 Javascript
深入浅析javascript中的作用域(推荐)
2016/07/19 Javascript
Google 地图控件集详解及实例代码
2016/08/06 Javascript
Angular懒加载机制刷新后无法回退的快速解决方法
2016/08/30 Javascript
Javascript中的 “&amp;” 和 “|” 详解
2017/02/02 Javascript
AngularJS实现的2048小游戏功能【附源码下载】
2018/01/03 Javascript
vue与vue-i18n结合实现后台数据的多语言切换方法
2018/03/08 Javascript
JS实现数组深拷贝的方法分析
2019/03/06 Javascript
js最实用string(字符串)类型的使用及截取与拼接详解
2019/04/26 Javascript
[42:32]Secret vs Optic 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/19 DOTA
python使用xauth方式登录饭否网然后发消息
2014/04/11 Python
详细解析Python中__init__()方法的高级应用
2015/05/11 Python
Python自动登录126邮箱的方法
2015/07/10 Python
深入源码解析Python中的对象与类型
2015/12/11 Python
简单谈谈Python流程控制语句
2016/12/04 Python
python中找出numpy array数组的最值及其索引方法
2018/04/17 Python
用python实现刷点击率的示例代码
2019/02/21 Python
Django框架之DRF 基于mixins来封装的视图详解
2019/07/23 Python
python实现的生成word文档功能示例
2019/08/23 Python
h5使用canvas画布实现手势解锁
2019/01/04 HTML / CSS
最经典的大学生职业生涯规划范文
2014/03/05 职场文书
个人租房协议书样本
2014/10/01 职场文书
老龙头导游词
2015/02/11 职场文书
企业办公室主任岗位职责
2015/04/01 职场文书
2016高中社会实践心得体会范文
2016/01/14 职场文书
秀!学妹看见都惊呆的Python小招数!【详细语言特性使用技巧】
2021/04/27 Python