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 相关文章推荐
JS小框架 fly javascript framework
Nov 26 Javascript
jquery中获得$.ajax()事件返回的值并添加事件的方法
Apr 15 Javascript
jQuery实现的经典滑动门效果
Sep 22 Javascript
jQuery Dialog对话框事件用法实例分析
May 10 Javascript
Bootstrap源码解读表单(2)
Dec 22 Javascript
Bootstrap源码解读模态弹出框(11)
Dec 28 Javascript
JQuery Dialog对话框 不能通过Esc关闭的原因分析及解决办法
Jan 18 Javascript
js实现前端图片上传即时预览功能
Aug 02 Javascript
细说webpack源码之compile流程-rules参数处理技巧(2)
Dec 26 Javascript
JavaScript对象的浅拷贝与深拷贝实例分析
Jul 25 Javascript
jQuery模拟html下拉多选框的原生实现方法示例
May 30 jQuery
vue中filters 传入两个参数 / 使用两个filters的实现方法
Jul 15 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中json_encode处理gbk与gb2312中文乱码问题的解决方法
2014/07/10 PHP
thinkphp连贯操作实例分析
2014/11/22 PHP
php框架CodeIgniter使用redis的方法分析
2018/04/13 PHP
php微信开发之关键词回复功能
2018/06/13 PHP
PHP创建文件及写入数据(覆盖写入,追加写入)的方法详解
2019/02/15 PHP
Laravel框架模型的创建及模型对数据操作示例
2019/05/07 PHP
jQuery中选择器小问题(新人难免遇到)
2014/03/31 Javascript
Nodejs中读取中文文件编码问题、发送邮件和定时任务实例
2015/01/01 NodeJs
简介alert()与console.log()的不同
2015/08/26 Javascript
js实现的Easy Tabs选项卡用法实例
2015/09/06 Javascript
详解Javascript函数声明与递归调用
2016/10/22 Javascript
原生js仿淘宝网商品放大镜效果
2017/02/28 Javascript
浅谈angular2的http请求返回结果的subcribe注意事项
2017/03/01 Javascript
轻松搞定jQuery+JSONP跨域请求的解决方案
2018/03/06 jQuery
解决Vue.js 2.0 有时双向绑定img src属性失败的问题
2018/03/14 Javascript
vue组件间的参数传递实例详解
2019/04/26 Javascript
layui table 列宽百分比显示的实现方法
2019/09/28 Javascript
简介JavaScript错误处理机制
2020/08/04 Javascript
用Python程序抓取网页的HTML信息的一个小实例
2015/05/02 Python
Python之自动获取公网IP的实例讲解
2017/10/01 Python
Python面向对象编程基础解析(一)
2017/10/26 Python
pandas series序列转化为星期几的实例
2018/04/11 Python
PyQt5每天必学之滑块控件QSlider
2018/04/20 Python
pandas筛选某列出现编码错误的解决方法
2018/11/07 Python
将Python字符串生成PDF的实例代码详解
2019/05/17 Python
Gauss-Seidel迭代算法的Python实现详解
2019/06/29 Python
python GUI库图形界面开发之PyQt5菜单栏控件QMenuBar的详细使用方法与实例
2020/02/28 Python
Python 调用有道翻译接口实现翻译
2020/03/02 Python
python实现控制台输出彩色字体
2020/04/05 Python
Python执行时间的几种计算方法
2020/07/31 Python
CSS3 网页下拉菜单代码解释 中文翻译
2010/02/27 HTML / CSS
美国男士内衣品牌:Tommy John
2017/12/22 全球购物
中专自我鉴定范文
2013/10/16 职场文书
大三毕业自我鉴定
2014/01/15 职场文书
现役军人家属慰问信
2015/03/24 职场文书
windows server2012 R2下安装PaddleOCR服务的的详细步骤
2022/09/23 Servers