1、識別瀏覽器呈現引擎
為了不在全局作用域中添加多余變量,這里使用單例模式(什么是單例模式?)來封裝檢測腳本。檢測腳本的基本代碼如下所示:
1 var client = function() { 2 var engine = { 3 ie: 0, 4 gecko: 0, 5 webkit: 0, 6 khtml: 0, 7 opera: 0, 8 9 // 具體的版本號 10 ver: null 11 }; 12 13 return { 14 engine: engine 15 } 16 }();
這里聲明了一個名為client的全局變量,用於保存相關信息。匿名函數內部定義了一個局部變量engine,它是一個包含默認設置的對象字面量。在這個對象字面量中,每個呈現引擎都對應着一個屬性,屬性的默認值是0。如果檢測到了哪個呈現引擎,那么就以浮點數值形式將該引擎的版本號寫入相應屬性。
要識別Opera,必須得檢測window.opera對象。Opera5及更高版本中都有這個對象,用於保存與瀏覽器相關的標識信息以及與瀏覽器直接交互。在Opera7.6及更高版本中,調用version()方法可以返回一個表示瀏覽器版本的字符串,而這也是確定Opera版本的最佳方式。要檢測更早的Opera,可以直接檢測用戶代理字符串,因為那些版本還不支持隱藏身份。不過2007底Opera的最高版本已經是9.5了,所以不太可能有人還使用7.6之前的版本。那么,檢測呈現引擎的代碼的第一步,就是編寫如下代碼:
1 if (window.opera) { 2 engine.ver = window.opera.version(); 3 engine.opra = parseFloat(engine.ver); 4 }
接下來檢測的引擎是webkit,因為webkit的用戶代理字符串中包含“Gecko”和“KHTML”這兩個子字符串,所以如果先檢測它們,都可能會得出錯誤的結論。
不過,Webkit的用戶代理字符串中的“AppleWebkit”是獨一無二的,因此檢測這個字符串是最合適的。下面就是檢測該字符串的示例代碼:
1 var ua = navigator.userAgent; 2 if (window.opera) { 3 engine.ver = window.opera.version(); 4 engine.opra = parseFloat(engine.ver); 5 } else if (/AppleWebkit\/(\S+)/i.test(ua)) { 6 engine.ver = RegExp['$1']; 7 engine.webkit = parseFloat(engine.ver); 8 }
接下來要測試的引擎是KHTML。同樣,KHTML的用戶代理字符串中也包含“Gecko”,因此在排除KHTML之前,我們無法准確檢測基於Gecko的瀏覽器。KHTML的版本號與Webkit的版本號在用戶代理字符串中的格式差不多,因此可以使用類似的正則表達式。此外,由於Konquerror 3.1及更早版本中不包含KHTML的版本,故而就要使用Konqueror的版本來代替。下面就是相應的檢測代碼。
1 var ua = navigator.userAgent; 2 if (window.opera) { 3 // 檢測opera 4 engine.ver = window.opera.version(); 5 engine.opra = parseFloat(engine.ver); 6 } else if (/AppleWebkit\/(\S+)/i.test(ua)) { 7 // 檢測webkit 8 engine.ver = RegExp['$1']; 9 engine.webkit = parseFloat(engine.ver); 10 } else if (/KHTML\/(\S+)/i.test(ua) || /Konqueror\/([^;]+)/i.test(ua)) { 11 // 檢測khtml 12 engine.ver = RegExp['$1']; 13 engine.khtml = parseFloat(engine.ver); 14 }
在排除了Webkit和KHTML之后,就可以准確地檢測Gecko了。但是,在用戶代理字符串中,Gecko的版本號不會出現在字符串“Gecko”的后面,而是會出現在字符串“rv:”的后面。這樣,我們就必須使用一個比前面復雜一些的正則表達式,如下所示。
1 var ua = navigator.userAgent; 2 if (window.opera) { 3 // 檢測opera 4 engine.ver = window.opera.version(); 5 engine.opra = parseFloat(engine.ver); 6 } else if (/AppleWebkit\/(\S+)/i.test(ua)) { 7 // 檢測webkit 8 engine.ver = RegExp['$1']; 9 engine.webkit = parseFloat(engine.ver); 10 } else if (/KHTML\/(\S+)/i.test(ua) || /Konqueror\/([^;]+)/i.test(ua)) { 11 // 檢測khtml 12 engine.ver = RegExp['$1']; 13 engine.khtml = parseFloat(engine.ver); 14 } else if (/rv:([^\)]+)\) Gecko\/\d{8}/i.test(ua)) { 15 // 檢測gecko 16 engine.ver = RegExp['$1']; 17 engine.gecko = parseFloat(engine.ver); 18 }
最后一個要檢測的就是IE了。IE的版本號們於字符串“MSIE”的后面、一個分號的前面,因此相應的正則表達式非常簡單,如下所示:
1 var ua = navigator.userAgent; 2 if (window.opera) { 3 // 檢測opera 4 engine.ver = window.opera.version(); 5 engine.opra = parseFloat(engine.ver); 6 } else if (/AppleWebkit\/(\S+)/i.test(ua)) { 7 // 檢測webkit 8 engine.ver = RegExp['$1']; 9 engine.webkit = parseFloat(engine.ver); 10 } else if (/KHTML\/(\S+)/i.test(ua) || /Konqueror\/([^;]+)/i.test(ua)) { 11 // 檢測khtml 12 engine.ver = RegExp['$1']; 13 engine.khtml = parseFloat(engine.ver); 14 } else if (/rv:([^\)]+)\) Gecko\/\d{8}/i.test(ua)) { 15 // 檢測gecko 16 engine.ver = RegExp['$1']; 17 engine.gecko = parseFloat(engine.ver); 18 } else if (/MSIE ([^;]+/i.test(ua))/) { 19 // 檢測ie 20 engine.ver = RegExp['$1']; 21 engine.ie = parseFloat(engine.ver); 22 }
2、識別瀏覽器
大多數情況下,識別了瀏覽器的呈現引擎就足以為我們采取正確的操作提供依據了。可是,只有呈現引擎還不能說明存在所需的JavaScript功能。蘋果公司的Safari瀏覽器和谷歌公司的Chrome瀏覽器都使用Webkit引擎,但它們的JavaScript引擎卻不一樣。在這兩款瀏覽器中,client.webkit都會返回非0值,但僅知道這一點恐怕還不夠。對於它們,有必要像下面這樣為client對象再添加一些新屬性。
1 var client = function() { 2 var engine = { 3 ie: 0, 4 gecko: 0, 5 webkit: 0, 6 khtml: 0, 7 opera: 0, 8 9 // 具體的版本號 10 ver: null 11 }; 12 13 var browser = { 14 // 瀏覽器 15 ie: 0, 16 firefox: 0, 17 safari: 0, 18 konq: 0, 19 opera: 0, 20 chrome: 0, 21 22 // 具體的版本號 23 ver: null 24 }; 25 26 return { 27 engine: engine, 28 browser: browser 29 } 30 }();
代碼中又添加了browser,用於保存每個主要瀏覽器的屬性。與engine變量一樣,除了當前使用的瀏覽器,其它屬性的值將保持為0。如果是當前使用的瀏覽器,則這個屬性中保存的是浮點數值形式的版本號。同樣,ver屬性中必要時將會包含字符串形式的瀏覽器完整版本號。由於大多數瀏覽器與呈現引擎密切相關,所以下面示例中檢測瀏覽器代碼與檢測呈現引擎的代碼是混合在一起的。
1 var client = function() { 2 var engine = { 3 ie: 0, 4 gecko: 0, 5 webkit: 0, 6 khtml: 0, 7 opera: 0, 8 9 // 具體的版本號 10 ver: null 11 }; 12 13 var browser = { 14 // 瀏覽器 15 ie: 0, 16 firefox: 0, 17 safari: 0, 18 konq: 0, 19 opera: 0, 20 chrome: 0, 21 22 // 具體的版本號 23 ver: null 24 }; 25 26 var ua = navigator.userAgent; 27 if (window.opera) { 28 // 檢測opera 29 engine.ver = browser.ver = window.opera.version(); 30 engine.opra = browser.opera = parseFloat(engine.ver); 31 } else if (/AppleWebkit\/(\S+)/i.test(ua)) { 32 // 檢測webkit 33 engine.ver = RegExp['$1']; 34 engine.webkit = parseFloat(engine.ver); 35 36 // 檢測Chrome/safari與其對應的版本 37 if (/Chrome\/(\S+)/i.test(ua)) { 38 browser.ver = RegExp['$1']; 39 browser.chrome = parseFloat(browser.ver); 40 } else if (/Version\/(\S+)/i.test(ua)) { 41 browser.ver = RegExp['$1']; 42 browser.safari = parseFloat(browser.ver); 43 } else { 44 // 當檢測不出Safari版本時,可大致確定safari的版本 45 var safariVersion = 1; 46 47 if (engine.webkit < 100) { 48 safariVersion = 1; 49 } else if (engine.webkit < 312) { 50 safariVersion = 1.2; 51 } else if (engine.webkit < 412) { 52 safariVersion = 1.3; 53 } else { 54 safariVersion = 2; 55 } 56 57 browser.safari = browser.ver = safariVersion; 58 } 59 } else if (/KHTML\/(\S+)/i.test(ua) || /Konqueror\/([^;]+)/i.test(ua)) { 60 // 檢測khtml 61 engine.ver = browser.ver = RegExp['$1']; 62 engine.khtml = browser.konq = parseFloat(engine.ver); 63 } else if (/rv:([^\)]+)\) Gecko\/\d{8}/i.test(ua)) { 64 // 檢測gecko 65 engine.ver = RegExp['$1']; 66 engine.gecko = parseFloat(engine.ver); 67 68 // 確定是不是Firefox 69 if (/Firefox\/(\S)+/i.test(ua)) { 70 browser.ver = RegExp['$1']; 71 browser.firefox = parseFloat(browser.ver); 72 } 73 } else if (/MSIE ([^;]+/i.test(ua))/) { 74 // 檢測ie 75 engine.ver = browser.ver = RegExp['$1']; 76 engine.ie = browser.ie = parseFloat(engine.ver); 77 } 78 79 return { 80 engine: engine, 81 browser: browser 82 } 83 }();
3、識別瀏覽器平台——操作系統
很多時候,只要知道呈現引擎足以編寫出適當的代碼了。但在某些條件下,平台可能是必須關注的問題。那些具有各個平台的瀏覽器(如Safari、Firefox、Opera)在不同的平台下可能會有不同的問題。目前的三大主流平台是Windows、Mac和Unix(包括各種Linux)。為了檢測這些平台,還需要像下面這樣添加一個新對象。
1 var client = function() { 2 var engine = { 3 ie: 0, 4 gecko: 0, 5 webkit: 0, 6 khtml: 0, 7 opera: 0, 8 9 // 具體的版本號 10 ver: null 11 }; 12 13 var browser = { 14 // 瀏覽器 15 ie: 0, 16 firefox: 0, 17 safari: 0, 18 konq: 0, 19 opera: 0, 20 chrome: 0, 21 22 // 具體的版本號 23 ver: null 24 }; 25 26 var system = { 27 win: false, 28 mac: false, 29 xll: false 30 }; 31 32 return { 33 engine: engine, 34 browser: browser 35 } 36 }();
在確定平台時,檢測navigator.platform要比檢測用戶代理字符串更簡單,后者在不同瀏覽器中會給出不同平台的信息。而navigator.platform屬性可能的值包括“Win32”、“Win64”、“MacPPC”、“MacIntel”、“Xll”和“Linux i686”,這些值在不同瀏覽器中都是一致的。檢測平台的代碼非常直觀,如下所示:
1 var p = navigator.platform; 2 system.win = p.indexOf('Win') == 0; 3 system.mac = p.indexOf('Mac') == 0; 4 system.xll = (p.indexOf('Xll') == 0 || p.indexOf('Linux') == 0);
4、識別Window操作系統
在Windows下台下,還可以從用戶代理字符串中進一步以得具體的操作系統信息。在WIndows XP之前,Windows有兩種版本,分別針對家庭版用戶和商業用戶。針對家庭用戶的版本分別是Windows 95、98和Windows ME。而針對商業用戶的版本則一直叫做Windows NT,最后由於市場原因改名為Windows 2000。這兩個產品后來又合並成一個由Windows NT發展而來的公共的代碼基,代表產品就是Winodws XP。隨后,微軟在Windows XP基礎上又構建Windows Vista。
只有了解這些信息,才能搞清楚用戶代理字符串中Winodws操作系統具體版本。下表列出了不同瀏覽器在表示不同Windows操作系統時給出的不同字符串。
windows版本 | IE4+ | Gecko | Opera | Webkit |
---|---|---|---|---|
95 | “Windows 95” | “Win95” | “Windows 95” | n/a |
98 | “Winodws 98” | “Win98” | “Windows 98” | n/a |
NT 4.0 | “Windows NT” | “WinNT4.0” | “windows NT 4.0” | n/a |
2000 | “Windows NT 5.0” | “Windows NT 5.0” | “Windows NT 5.0” | n/a |
ME | “Win 9x 4.90” | “Win 9x 4.90” | “Win 9x 4.90” | n/a |
XP | “Windows NT 5.1” | “Windows NT 5.1” | “Windows NT 5.1” | “Windows NT 5.1” |
Vista | “Windows NT 6.0” | “Windows NT 6.0” | “Windows NT 6.0” | “Windows NT 6.0” |
7 | “Windows NT 6.1” | “Windows NT 6.1” | “Windows NT 6.1” | “Windows NT 6.1” |
8 | “Windows NT 6.2” | “Windows NT 6.2” | “Windows NT 6.2” | “Windows NT 6.2” |
由於用戶代理字符串中的Windows操作系統版本表示方法各異,因此檢測代碼並不十分直觀。好在,從Windows 2000開始,表示操作系統的字符串大部分都還相同,只有版本號有變化。為了檢測不同的Windows操作系統,必須使用正則表達式。
第一步就是匹配Winodws 95和Windows 98這兩個字符串。對這兩個字符串,只有Gecko與其它瀏覽器不同,即沒有"dows",而且"win"與版本號之間沒有空格。要匹配這個模式,可以使用下面這個簡單的正則表達式:
1 /Win(?:dows )?([^do]{2})/i
這個正則表達式中捕獲的數組會返回操作系統的版本。由於版本可能是任何兩個字符編碼(例如 95、98、9x、NT、ME及XP),因此要使用兩個非空空格字符。
Gecko在表示Windows NT時會在末尾添加“4.0”,與其查找實際字符串,不如像現在這樣查找小數值更合適。
1 /Win(?:dows )?([^do]{2})(\d+\.\d+)?/i
這樣,正則表達式中就包含了第二個捕獲組,用於取得NT的版本號。由於該版本號對於Windows 95、98而言是不存在的,所以必須設置為可選。這個模式與Opera表示Windows NT的字符串之間唯一的區別,就是“NT”與“4.0”之間的空格,這在模式中很容易添加。
1 /Win(?:dows )?([^do]{2})\s+(\d+\.\d+)?/i
經過一番修改后,這個正則表達式也可以成功匹配Windows ME、Windows XP和Windows Vista的字符串了。具體來說,第一個捕獲數組將會匹配95、98、9x、NT、ME或XP。第二個捕獲數組則只針對Windows ME及所有WIndows NT的變體。這個信息作為具體的操作系統信息保存在system.win屬性中,如下所示:
1 if (system.win) { 2 if (/Win(?:dows )?([^do]{2})\s?(\d+\.\d+)?/i.test(ua)) { 3 if (RegExp['$1'] == 'NT') { 4 switch (RegExp['$2']) { 5 case '5.0': system.win = '2000'; break; 6 case '5.1': system.win = 'XP'; break; 7 case '6.0': system.win = 'Vista'; break; 8 case '6.1': system.win = '7'; break; 9 case '6.2': system.win = '8'; break; 10 default: system.win = 'NT'; break; 11 } 12 } else if (RegExp['$1'] == '9x') { 13 system.win = 'ME'; 14 } else { 15 system.win = RegExp['$1']; 16 } 17 } 18 }
5、識別移動設備
2006到2007年,移動設備中Web瀏覽器的應用呈爆炸式增長。四大主要瀏覽器都推出了手機版和其它設備中運行的版本。要檢測相應的設備,第一步是為要檢測的所有移動設備添加屬性,如下所示:
1 var client = function() { 2 var engine = { 3 ie: 0, 4 gecko: 0, 5 webkit: 0, 6 khtml: 0, 7 opera: 0, 8 9 // 具體的版本號 10 ver: null 11 }; 12 13 var browser = { 14 // 瀏覽器 15 ie: 0, 16 firefox: 0, 17 safari: 0, 18 konq: 0, 19 opera: 0, 20 chrome: 0, 21 22 // 具體的版本號 23 ver: null 24 }; 25 26 var system = { 27 win: false, 28 mac: false, 29 xll: false, 30 31 // 移動設備 32 iphone: false, 33 ipod: false, 34 ipad: false, 35 ios: false, 36 android: false, 37 nokiaN: false, 38 winMobile: false 39 }; 40 41 return { 42 engine: engine, 43 browser: browser, 44 system: system 45 } 46 47 }();
然后,通過簡單地檢測字符串“iPhone”、"iPod"和"iPad"就可以分別設置相應屬性的值了。
1 system.iphone = ua.indexOf('iPhone') > -1; 2 system.ipod = ua.indexOf('iPod') > -1; 3 system.ipad = ua.indexOf('iPad') > -1;
除了知道IOS設備,最好還知道IOS的版本號。在IOS之前,用戶代理字符串中只包含“CPU like Mac OS”,后來iPhone中又改成“CPU iPhone OS 3_0 like Mac OS X”,iPad又改成“CPU OS 3_2 like Mac OS X”。也就是說,檢測IOS需要正則表達式反映這些變化。
1 // 檢測ios版本 2 if (system.mac && ua.indexOf('Mobile') > -1) { 3 if (/CPU (?:iPhone )?OS (\d+_\d+)/i.test(ua)) { 4 system.ios = parseFloat(RegExp['$1'].replace('_', '.')); 5 } else { 6 system.ios = 2; // 不能真正檢測出來,所以只能猜測 7 } 8 }
檢測系統是不是Mac OS、字符串中是否存在“Mobile”,可以保證無論是什么版本,system.ios中都不會是0。然后,再使用正則表達式確定是否存在IOS的版本號。如果有,將system.ios設置為表示版本號的浮點值;否則,將版本號設置為2。(因為沒有辦法確定到底是什么版本,所以設置為更早的版本比較穩妥)
檢測Android版本操作系統也很簡單,也就是搜索字符串“Android”並取得緊隨其后的版本號。
1 // 檢測android版本 2 if (/Android (\d+\.\d+)/i.test(ua)) { 3 system.android = parseFloat(RegExp['$1']); 4 }
由於所有的Android都有版本值,因此使用這個正則表達式可以精確的檢測所有版本,並將system.android設置為正確的值。
諾基亞N系統手機使用的也是Webkit,其用戶代理字符串與其它基於webkit的手機很相似。雖然諾基亞N系列手機在用戶代理字符串中聲稱使用的是“safari”,但實際上並不是safari,盡管確實是基於webkit引擎。只要使用下面檢測一下用戶代理字符串中是否存在“NokiaN”,就足以確定是不是該系列的手機了。
1 // 檢測nokia 2 system.nokiaN = ua.indexOf('NokiaN') > -1;
最后一種主要的移動設備平台是Windows Mobile(也稱Windows CE),用於Pocket PC和Smartphone中。由於從技術上說這些平台都屬於Windows平台,因此Windows平台和操作系統都會返回正確的值。對於Windows Mobile 5.0及以前的版本,這兩種設備的用戶代理字符串非常相似,如下所示:
Mozilla/4.0 (compatible; MSIE 4.01; Windows CE; PPC; 240x320)
Mozilla/4.0 (compatible; MSIE 4.01; Windows CE; Smartphone; 176x220)
這一個來自Pocket PC中的移動Internet Explorer 4.01,第二個來自Smartphone中的同一個瀏覽器。當Windows操作系統檢測腳本檢測到這兩個字符串時,system.win將被設置成"CE",因此在檢測Windows Mobile時可以使用這個值:
1 // 檢測Windows Mobile 2 system.winMobile = (system.win == 'CE');
不建議測試字符串中的“PPC”或“Smartphone”,因為在Windows Mobile 5.0以后版本的瀏覽器中,這些記號已經被移除了。不過,一般情況下,只知道這某個設備使用的是Windows Mobile也就足夠了。
Windows Phone 7的用戶代理字符串稍有改進,基本格式如下:
Mozilla/4.0 (compatible; MSIE 7.0; Windows Phone OS 7.0; Trident/3.1; IEMobile/7.0) Asus;Galaxy6
其中,Windows操作符的標簽符與已往完全不同,因此在這個用戶代理中,clinet.system.win等於"ph"。從中可以取得有關系統的更多信息:
1 // 檢測Windows Mobile 2 if (system.win == 'CE') { 3 system.winMobile = system.win; 4 } else if (system.win == 'Ph') { 5 if (/Windows Phone OS (\d+.\d+)/i.test(ua)) { 6 system.win = 'Phone'; 7 system.winMobile = parseFloat(RegExp['$1']); 8 } 9 }
如果system.win的值是"CE",就說明是老版本的Windows Mobile,因此system.winMobile會被設置為相同的值(只能知道這個信息)。如果system.win的值是“Ph”,那么這個設置就可能是Windows Phone7或更新版本。因此就用正則表達式來測試格式並提取版本號,將system.win的值重置為"Phone",而將system.winMobile設置為版本號。
6、識別游戲系統
除了移動設備之外,視頻游戲系統中的Web瀏覽器也開始日益普及。Wii中的瀏覽器實際上是定制版的Opera,是專門為Wii Remote設計的。Playstation的瀏覽器是自己開發的,沒有基於前面提到的任何呈現引擎。這兩個中的用戶代理字符串如下所示:
Opera/9.10 (Nintendo Wii; U; ; 1621; en)
Mozilla/5.0 (PLAYSTATION 3; 2.00)
在檢測這些設置以前,我們必須先為client.system中添加適當的屬性,如下所示:
1 var client = function() { 2 var engine = { 3 ie: 0, 4 gecko: 0, 5 webkit: 0, 6 khtml: 0, 7 opera: 0, 8 9 // 具體的版本號 10 ver: null 11 }; 12 13 var browser = { 14 // 瀏覽器 15 ie: 0, 16 firefox: 0, 17 safari: 0, 18 konq: 0, 19 opera: 0, 20 chrome: 0, 21 22 // 具體的版本號 23 ver: null 24 }; 25 26 var system = { 27 win: false, 28 mac: false, 29 xll: false, 30 31 // 移動設備 32 iphone: false, 33 ipod: false, 34 ipad: false, 35 ios: false, 36 android: false, 37 nokiaN: false, 38 winMobile: false, 39 40 // 游戲系統 41 wii: false, 42 ps: false 43 }; 44 45 return { 46 engine: engine, 47 browser: browser, 48 system: system 49 } 50 51 }();
檢測前述游戲系統的代碼如下:
1 // 檢測游戲系統 2 system.wii = ua.indexOf('Wii') > -1; 3 system.ps = /playstation/i.test(ua);
完整的代碼:

1 var client = function() { 2 var engine = { 3 ie: 0, 4 gecko: 0, 5 webkit: 0, 6 khtml: 0, 7 opera: 0, 8 ver: null 9 }; 10 11 var browser = { 12 ie: 0, 13 firefox: 0, 14 safari: 0, 15 konq: 0, 16 opera: 0, 17 chrome: 0, 18 ver: null 19 }; 20 21 var system = { 22 win: false, 23 mac: false, 24 xll: false, 25 iphone: false, 26 ipoad: false, 27 ipad: false, 28 ios: false, 29 android: false, 30 nokiaN: false, 31 winMobile: false, 32 wii: false, 33 ps: false 34 }; 35 36 var ua = navigator.userAgent; 37 // 檢測瀏覽器呈現引擎 38 if (window.opera) { 39 engine.ver = browser.ver = window.opera.version(); 40 engine.opera = browser.opera = parseFloat(engine.ver); 41 } else if (/AppleWebkit\/(\S+)/i.test(ua)) { 42 engine.ver = RegExp['$1']; 43 engine.webkit = parseFloat(engine.ver); 44 45 // 確定是Chrome還是Safari 46 if (/Chrome\/(\S+)/i.test(ua)) { 47 browser.ver = RegExp['$1']; 48 browser.chrome = parseFloat(browser.ver); 49 } else if (/Version\/(\S+)/i.test(ua)) { 50 browser.ver = RegExp['$1']; 51 browser.safari = parseFloat(browser.ver); 52 } else { 53 // 近似地確定版本號 54 var safariVersion = 1; 55 if (engine.webkit < 100) { 56 safariVersion = 1; 57 } else if (engine.webkit < 312) { 58 safariVersion = 1.2; 59 } else if (engine.webkit < 412) { 60 safariVersion = 1.3; 61 } else { 62 safariVersion = 2; 63 } 64 65 browser.safari = browser.safari = safariVersion; 66 } 67 } else if (/KHTML\/(\S+)/i.test(ua) || /Konqueror\/([^;]+)/i.test(ua)) { 68 engine.ver = browser.ver = RegExp['$1']; 69 engine.khtml = browser.konq = parseFloat(engine.ver); 70 } else if (/rv:([^\)]+)\) Gecko\/\d{8}/i.test(ua)) { 71 engine.ver = RegExp['$1']; 72 engine.gecko = parseFloat(engine.ver); 73 74 // 確定是不是Firefox 75 if (/Firefox\/(\S+)/i.test(ua)) { 76 engine.ver = browser.ver = RegExp['$1']; 77 engine.firefox = parseFloat(browser.ver); 78 } 79 } else if (/MSIE ([^;]+)/i.test(ua)) { 80 engine.ver = browser.ver = RegExp['$1']; 81 engine.ie = browser.ie = parseFloat(engine.ver); 82 } 83 84 // 檢測平台 85 var p = navigator.platform; 86 system.win = p.indexOf('Win') == 0; 87 system.mac = p.indexOf('Mac') == 0; 88 system.xll = (p.indexOf('Xll') == 0 || p.indexOf('Linux') == 0); 89 90 // 檢測Windows操作系統 91 if (system.win) { 92 if (/Win(?:dows )?([^do]{2})\s?(\d+\.\d+)?/.test(ua)) { 93 if (RegExp['$1'] == 'NT') { 94 switch(RegExp['$2']) { 95 case '5.0': system.win = '2000'; break; 96 case '5.1': system.win = 'XP'; break; 97 case '6.0': system.win = 'Vista'; break; 98 case '6.1': system.win = '7'; break; 99 case '6.2': system.win = '8'; break; 100 default: system.win = 'NT'; break; 101 } 102 } else if (RegExp['$1'] == '9x') { 103 system.win = 'ME'; 104 } else { 105 system.win = RegExp['$1']; 106 } 107 } 108 } 109 110 // 移動設備 111 system.iphone = ua.indexOf('iPhone') > -1; 112 system.ipod = ua.indexOf('iPod') > -1; 113 system.ipad = ua.indexOf('iPad') > -1; 114 system.nokiaN = ua.indexOf('nokiaN') > -1; 115 116 // windows mobile 117 if (system.win == 'CE') { 118 system.winMobile = system.win; 119 } else if (system.win == 'Ph') { 120 if (/Windows Phone OS (\d+.\d)/i.test(ua)) { 121 system.win = 'Phone'; 122 system.winMobile = parseFloat(RegExp['$1']); 123 } 124 } 125 126 // 檢測IOS版本 127 if (system.mac && ua.indexOf('Mobile') > -1) { 128 if (/CPU (?:iPhone )?OS (\d+_\d+)/i.test(ua)) { 129 system.ios = parseFloat(RegExp['$1'].replace('_', '.')); 130 } else { 131 system.ios = 2; // 不能真正檢測出來,所以只能猜測 132 } 133 } 134 135 // 檢測Android版本 136 if (/Android (\d+\.\d+)/i.test(ua)) { 137 system.android = parseFloat(RegExp['$1']); 138 } 139 140 // 游戲系統 141 system.wii = ua.indexOf('Wii') > -1; 142 system.ps = /PlayStation/i.test(ua); 143 144 return { 145 engine: engine, 146 browser: browser, 147 system: system 148 } 149 }();
(注:原文摘自《JavaScript高級程序設計》第3版,第9章 客戶端檢測,9.3用戶代理檢測,p221)