一、檢測浏覽器的名稱 問題: 不同的浏覽器對JavaScript的标準支援也有不同,有時希望腳本能夠在不同的浏覽器上都能運作良好,這時需要對浏覽器進行檢測,确定其名稱,以針對不同的浏覽器編寫相應的腳本。 解決方案: 使用navigator對象的appName屬性。 比如,要檢測浏覽器是否為IE,可以這麼做: var isIE = (navigator.appName == "Microsoft Internet Explorer"); document.write("is IE?" + isIE); 對于FireFox,navigator對象的appName屬性值為"Netscape";Opera9.02的appName屬性值為"Opera"(其更早版本可能不同);
二、檢測浏覽器的版本号: 問題: 随着浏覽器的版本的更疊,浏覽器所支援的腳本特性也在變化,有時候就需要針對不同的版本編寫相應的腳本,那麼如何獲得浏覽器的版本号? 解決方案: 通過解析navigator對象的userAgent屬性來獲得浏覽器的完整版本号。 IE将自己辨別為MSIE,後面帶一個空格,版本号以及分号。是以我們隻要取空格和分号之間的部分即可。如Windows XP SP2所帶的IE的userAgent屬性值為"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)",可以看到其版本為6.0。可以用如下的函數來擷取IE浏覽器的版本号: function getIEVersonNumber() { var ua = navigator.userAgent; var msieOffset = ua.indexOf("MSIE "); if(msieOffset < 0) { return 0; } return parseFloat(ua.substring(msieOffset + 5, ua.indexOf(";", msieOffset))); } 假設我們要為IE5及以上版本編寫腳本,可以這麼寫: var isIE5Min = (getIEVersonNumber() >= 5); if(isIE5Min) { // perform statements for IE 5 or later } 對于FireFox和Opera等浏覽器,也可以用navigator.userAgent屬性來擷取其版本号,隻不過其形式與IE有所不同,如FireFox: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.7) Gecko/20060909 Firefox/1.5.0.7 Opera:Opera/9.02 (Windows NT 5.1; U; en)根據這些形式,我們不難獲得其版本号。但這些浏覽器的其它版本沒有測試過,其具體值不明确,如果要使用這種方法檢測,請自行驗證。
下面讨論下,上面的那段為IE5及以上版本浏覽器編寫的腳本,使用這種寫法要注意:要用>=而不是==,一般情況下,我們可以假定浏覽器是向後相容的,是以使用==顯然不能适應新版本;另一方面,我們上面的假定也僅僅是假定,不能確定是這樣,如果浏覽器的某些對象或屬性不能向後相容,我們的代碼也會産生問題,是以建議,少用浏覽器版本的比較,更多情況下,應檢測是要用的對象或屬性是否得到支援。
三、檢測用戶端的作業系統類型 根據上面的讨論可以看到,navigator.userAgent屬性通常含有作業系統的基本資訊,但很不幸,沒有統一的規則去根據userAgent擷取準确的作業系統資訊,因為這些值與浏覽器的種類、浏覽器的版本甚至浏覽器的OEM版本都有關系。 通常我們能做的是,檢測一些更為通用的資訊,比如作業系統是Windows還是Mac,而不是去看是Windows 98還是Windows XP。其規則是所有的Windows版本都會含有"Win",所有的Macintosh版本都含有"Mac",所有的Unix則含有"X11",而在Linux下則同時包含"X11"和"Linux"。如: var isWin = (navigator.userAgent.indexOf("Win") != -1); var isMac = (navigator.userAgent.indexOf("Mac") != -1); var isUnix = (navigator.userAgent.indexOf("X11") != -1); 通常用在為不同的作業系統設定不同的字型或位置等樣式。
四、檢測浏覽器對特定對象的支援 問題: 如果需要編寫對多種浏覽器或浏覽器的多個版本都能适用的腳本,就要進行檢測一下,浏覽器是否支援某個對象。當然這種檢測主要是針對那些潛在的不相容對象的語句。 解決方案: 早期的浏覽器對于img元素的支援差别很大,是以要在腳本中操作img元素,需要檢測浏覽器是否支援。這時我們不需要對所有可能的浏覽器一一檢測,隻需在必要的地方用下面的方式檢測: function rollover(imgName, imgSrc) { // 如果支援images對象 if(document.images) { // statements go here } } 這種方法能夠生效是基于一個事實:如果document.images對象不存在,那麼if求值的結果為false。
使用這種方法,使得對對象的檢測變得簡單易行,但是我們要注意,對于那些不支援該對象的浏覽器要如何較好得處理。看下面的代碼: function getImgAreas() { var result = 0; for(var i = 0; i < document.images.length; i++) { result += (document.images[i].width * document.images[i].height); } return result; } function reportImageArea() { document.form1.imgData.value = getImgAreas(); } 這裡沒用對象支援的檢測。如果浏覽器支援document.images,這兩個函數運作正常;否則就會抛出異常。下面是改進的腳本: function getImgAreas() { var result; // 檢測浏覽器是否支援對象 if (document.images) { result = 0; for (var i = 0; i < document.images.length; i++) { result += (document.images[i].width * document.images[i].height); } } // 傳回值為一個數字或null return result; } function reportImageArea() { // 現在可以判斷傳回值 var imgArea = getImgAreas(); var output; if (imgArea == null) { // 對于不支援images對象的浏覽器也要給出相應資訊 output = "Unknown"; } else { output = imgArea; } document.reportForm.imgData.value = output; } 這樣,不管浏覽器是否支援該對象,都能給使用者比較合理的資訊,而不會跳出突兀的錯誤資訊。
五、檢測浏覽器對特定屬性和方法的支援 問題: 檢測一個對象是否含有某個特定的屬性或方法。 解決方案: 大多數情況下,可以用類似于下面的代碼來判斷: if(objectTest && objectPropertyTest) { // OK to work with property } 先檢測對象是否存在,然後再檢測對象的屬性是否存在。如果對象确實不存在,該方法有效;如果屬性存在,但其值為null, 0, false,if語句求值的結果也将是false!是以這種方法并不安全,最好的方法是這樣: if (objectReference && typeof(objectReference.propertyName) != "undefined") { // OK to work with property } 對于方法的檢測也可用類似的方法: function myFunction() { if (document.getElementById) { // 這裡可以使用getElementById方法 } }
Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.8.1.2) Gecko/20070219 Firefox/2.0.0.2 Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; TencentTraveler ; .NET CLR 2.0.50727) Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; TencentTraveler ; .NET CLR 2.0.50727) Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; TencentTraveler ; .NET CLR 2.0.50727)