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 通过事件委派一次绑定多种事件,以减少事件冗余
Jun 30 Javascript
jQuery Ajax 仿AjaxPro.Utility.RegisterTypeForAjax辅助方法
Sep 27 Javascript
javascript图像处理—仿射变换深度理解
Jan 16 Javascript
JQUERY实现左侧TIPS滑进滑出效果示例
Jun 27 Javascript
SeaJS入门教程系列之完整示例(三)
Mar 03 Javascript
jQuery实现菜单式图片滑动切换
Mar 14 Javascript
jquery可定制的在线UEditor编辑器
Nov 17 Javascript
JS中的hasOwnProperty()、propertyIsEnumerable()和isPrototypeOf()
Aug 11 Javascript
Angularjs中三种数据的绑定策略(“@”,“=”,“&amp;”)
Dec 23 Javascript
浅谈javascript中的 “ &amp;&amp; ” 和 “ || ”
Feb 02 Javascript
javascript 面向对象function详解及实例代码
Feb 28 Javascript
微信小程序实现选择地址省市区三级联动
Jun 21 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下实现折线图效果的代码
2007/04/28 PHP
php+js实现异步图片上传实例分享
2014/06/02 PHP
php函数serialize()与unserialize()用法实例
2014/11/06 PHP
PDO::lastInsertId讲解
2019/01/29 PHP
33种Javascript 表格排序控件收集
2009/12/03 Javascript
node.js实现端口转发
2016/04/14 Javascript
JavaScript交换两个变量值的七种解决方案
2016/12/01 Javascript
jQuery移除或禁用html元素点击事件常用方法小结
2017/02/10 Javascript
JS区分Object与Aarry的六种方法总结
2017/02/27 Javascript
微信小程序 template模板详解及实例代码
2017/03/09 Javascript
jQuery选择器中的特殊符号处理方法
2017/09/08 jQuery
详解webpack与SPA实践之开发环境搭建
2017/12/18 Javascript
Vue 表情包输入组件的实现代码
2019/01/21 Javascript
浅谈Webpack多页应用HMR卡住问题
2019/04/24 Javascript
vue实现移动端图片上传功能
2019/12/23 Javascript
JavaScript实现字符串与HTML格式相互转换
2020/03/17 Javascript
python创建线程示例
2014/05/06 Python
Python学习笔记之常用函数及说明
2014/05/23 Python
对Python3 pyc 文件的使用详解
2019/02/16 Python
Python3.5内置模块之random模块用法实例分析
2019/04/26 Python
Python Web框架之Django框架Model基础详解
2019/08/16 Python
Python上下文管理器用法及实例解析
2019/11/11 Python
调用其他python脚本文件里面的类和方法过程解析
2019/11/15 Python
Python笔记之facade模式
2019/11/20 Python
如何在django中添加日志功能
2020/02/06 Python
Python调用OpenCV实现图像平滑代码实例
2020/06/19 Python
北美最大的手工艺品零售商之一:Michaels Stores
2019/02/27 全球购物
英国100%防污和防水的靴子:Muck Boot Company
2020/09/08 全球购物
会议邀请函范文
2014/01/09 职场文书
机关办公室岗位职责
2014/04/16 职场文书
岗位工作说明书
2014/07/29 职场文书
世界文化遗产导游词
2015/02/13 职场文书
班组长如何制订适合本班组的工作计划?
2019/07/10 职场文书
关于Javascript闭包与应用的详解
2021/04/22 Javascript
react antd实现动态增减表单
2021/06/03 Javascript
Spring Security使用单点登录的权限功能
2022/04/03 Java/Android