YUI.UA是针对javascript的宿主环境检测的一个检测对象,返回的是一系统关于当前宿主的信息
1.对象相关信息列表及userAgent


检测对象o = {ie: 0, //ie Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E) opera: 0, //opera Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.57 Safari/537.36 OPR/16.0.1196.62 gecko: 0, // ff Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20100101 Firefox/23.0webkit: 0, //检测webkit内核版本safari: 0, //safari Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.57.2 (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2chrome: 0, //chrome Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.10 Safari/537.36 mobile: null, //检测是否是手机 Mozilla/5.0 (Linux; U; Android 2.3.6; en-us; Nexus S Build/GRK39F) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1 (Android)air: 0, //检测 Adobe AIR的版本phantomjs: 0, //phantomjs 是以webkit为核心并提供javascript编程接口(API)的无显示浏览器ipad: 0, //ipad Mozilla/5.0 (iPad; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5376e Safari/8536.25iphone: 0, //iphone Mozilla/5.0 (iPhone; CPU iPhone OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5376e Safari/8536.25 ipod: 0,ios: null, //ios系统 iphone | ipad | ipod android: 0, //android 系统silk: 0, // 亚马逊推出的基于安卓的平板浏览器 全名为Kindle Silkaccel: false, //Kindle Silk是否启动加速webos: 0, //weboscaja: nav && nav.cajaVersion, //google发起的让javascript更安全的caja项目secure: false, //SSL中是否设置os: null, //操作系统,目前仅检测window或macintoshnodejs: 0, //nodejs版本winjs: !!((typeof Windows !== "undefined") && Windows.System), //window8与ie10的应用环境touchEnabled: false //是否支持触摸},
2.定义一个公用函数,用于检测版本号


版本检测函数var numberify = function(s) {var c = 0;return parseFloat(s.replace(/\./g, function() {return (c++ === 1) ? '' : '.';}));},
这个函数的就是将’123.234.42.42424’ => 123.23442
变更一下 :保留第一个符号,后面相同的符号全部去掉


版本检测函数var numberify = function (s) {var i = 0;return parseFloat(s.replace(/\./g,function(){return ( i++ === 0 ) ? '.' : '';}) } // '1.2.3.4.5.6' ==> 1.23456 来自http://zhangyaochun.iteye.com/blog/1840297
再变更一下:获取一个寻址


版本检测函数//最快的也是seajs采用的 function dirname (path) {var s = path.match ( /.*(?=\/.*$)/);return ( s ? s[0] : '.' ) + '/'; } //第二种 function dirname(path){var s = path.split('/').slice(0,-1).join('/');return s ? s : '.'; } 第三种 function dirname(path){var s = ('./' + path).replace(/(.*)?\/.*/, '$1').substring(2);return s ? s : '.'; } /* "a.js" ===> "./"* "a/b.js" ===> "a/"* "a/b/c.js" ===> "a/b/"来自 http://zhangyaochun.iteye.com/blog/1693798 */
3.开始检测


版本检测函数YUI.UA = function (subUA) {//numberify函数//o对象//nav,ua赋值 nav = window.navigator ua = subUA || nav && nav.userAgenthref = window.location && window.location.hrefo.userAgent = ua }
a. 安全设置o.secure是根据href中是否以https开始来设置值 (http与https的区 别http://www.cnblogs.com/wxlzhizu/archive/2009/12/09/1620005.html)
o.secure = href && (href.toLowerCase().indexOf(‘https’) === 0);
b. 检测顺序如下 (操作系统 –> 检测内核及是否是手机 –> 检测webkit内核 【opera15+特殊,手机项】 –> 检测不是webkit 【opera低版本】 –> IE


检测顺序if (ua) {//检测操作系统if ((/windows|win32/i).test(ua)) {o.os = 'windows';} else if ((/macintosh|mac_powerpc/i).test(ua)) {o.os = 'macintosh';} else if ((/android/i).test(ua)) {o.os = 'android';} else if ((/symbos/i).test(ua)) {o.os = 'symbos';} else if ((/linux/i).test(ua)) {o.os = 'linux';} else if ((/rhino/i).test(ua)) {o.os = 'rhino';}// Modern KHTML browsers should qualify as Safari X-Gradeif ((/KHTML/).test(ua)) {o.webkit = 1;}if ((/IEMobile|XBLWP7/).test(ua)) {o.mobile = 'windows';}if ((/Fennec/).test(ua)) {o.mobile = 'gecko';}// Modern WebKit browsers are at least X-Grade 检测webkit类浏览器m = ua.match(/AppleWebKit\/([^\s]*)/);if (m && m[1]) {o.webkit = numberify(m[1]);o.safari = o.webkit;if (/PhantomJS/.test(ua)) {m = ua.match(/PhantomJS\/([^\s]*)/);if (m && m[1]) {o.phantomjs = numberify(m[1]);}}// Mobile browser check 手机项if (/ Mobile\//.test(ua) || (/iPad|iPod|iPhone/).test(ua)) {o.mobile = 'Apple'; // iPhone or iPod Touchm = ua.match(/OS ([^\s]*)/);if (m && m[1]) {m = numberify(m[1].replace('_', '.'));}o.ios = m;o.os = 'ios';o.ipad = o.ipod = o.iphone = 0;m = ua.match(/iPad|iPod|iPhone/);if (m && m[0]) {o[m[0].toLowerCase()] = o.ios; //设置iphone ipod ipad的版本}} else {m = ua.match(/NokiaN[^\/]*|webOS\/\d\.\d/);if (m) {// Nokia N-series, webOS, ex: NokiaN95o.mobile = m[0];}if (/webOS/.test(ua)) {o.mobile = 'WebOS';m = ua.match(/webOS\/([^\s]*);/);if (m && m[1]) {o.webos = numberify(m[1]);}}if (/ Android/.test(ua)) {if (/Mobile/.test(ua)) {o.mobile = 'Android';}m = ua.match(/Android ([^\s]*);/);if (m && m[1]) {o.android = numberify(m[1]);}}if (/Silk/.test(ua)) {m = ua.match(/Silk\/([^\s]*)\)/);if (m && m[1]) {o.silk = numberify(m[1]);}if (!o.android) {o.android = 2.34; //Hack for desktop mode in Kindleo.os = 'Android';}if (/Accelerated=true/.test(ua)) {o.accel = true;}}}m = ua.match(/OPR\/(\d+\.\d+)/); //以OPR来作条件是因为opera15+ ua中会有chrome safari OPR的版本号if (m && m[1]) {// Opera 15+ with Blink (pretends to be both Chrome and Safari) opera15+采用chromium引擎o.opera = numberify(m[1]);} else {m = ua.match(/(Chrome|CrMo|CriOS)\/([^\s]*)/);if (m && m[1] && m[2]) {o.chrome = numberify(m[2]); // Chromeo.safari = 0; //Reset safari back to 0if (m[1] === 'CrMo') {o.mobile = 'chrome';}} else {m = ua.match(/AdobeAIR\/([^\s]*)/);if (m) {o.air = m[0]; // Adobe AIR 1.0 or better}}}}if (!o.webkit) { // not webkit// @todo check Opera/8.01 (J2ME/MIDP; Opera Mini/2.0.4509/1316; fi; U; ssr)if (/Opera/.test(ua)) {m = ua.match(/Opera[\s\/]([^\s]*)/);if (m && m[1]) {o.opera = numberify(m[1]);}m = ua.match(/Version\/([^\s]*)/);if (m && m[1]) {o.opera = numberify(m[1]); // opera 10+}if (/Opera Mobi/.test(ua)) {o.mobile = 'opera';m = ua.replace('Opera Mobi', '').match(/Opera ([^\s]*)/);if (m && m[1]) {o.opera = numberify(m[1]);}}m = ua.match(/Opera Mini[^;]*/);if (m) {o.mobile = m[0]; // ex: Opera Mini/2.0.4509/1316}} else { // not opera or webkitm = ua.match(/MSIE ([^;]*)|Trident.*; rv:([0-9.]+)/);if (m && (m[1] || m[2])) {o.ie = numberify(m[1] || m[2]);} else { // not opera, webkit, or iem = ua.match(/Gecko\/([^\s]*)/);if (m) {o.gecko = 1; // Gecko detected, look for revisionm = ua.match(/rv:([^\s\)]*)/);if (m && m[1]) {o.gecko = numberify(m[1]);if (/Mobile|Tablet/.test(ua)) {o.mobile = "ffos";}}}}}}}
c. 是否支持触摸检测


触摸if (win && nav && !(o.chrome && o.chrome < 6)) {o.touchEnabled = (("ontouchstart" in win) || (("msMaxTouchPoints" in nav) && (nav.msMaxTouchPoints > 0)));}
d.不是客户端版的js检测


nodejsif (!subUA) {if (typeof process === 'object') {if (process.versions && process.versions.node) {//NodeJSo.os = process.platform;o.nodejs = numberify(process.versions.node);}}YUI.Env.UA = o;}
4.版本比较函数,采用sort中函数的写法


版本比较函数compareVersions = function (a, b) {var aPart, aParts, bPart, bParts, i, len;if (a === b) {return 0;}//转换成数组aParts = (a + '').split('.');bParts = (b + '').split('.');//取两个数组中元素多的为长度进行循环for (i = 0, len = Math.max(aParts.length, bParts.length); i < len; ++i) {aPart = parseInt(aParts[i], 10);bPart = parseInt(bParts[i], 10);/*jshint expr: true*/isNaN(aPart) && (aPart = 0);isNaN(bPart) && (bPart = 0);if (aPart < bPart) {return -1;}if (aPart > bPart) {return 1;}}return 0; };