一、前言 苦逼的前端攻城獅都深受瀏覽器安全色之苦,再完成每一項功能前都要左顧右盼,生怕瀏覽器不支援某個API,生怕原生API內含臭蟲因此判斷瀏覽器類型和版本號碼成了不可繞過的一道關卡,而特徵嗅探是繼瀏覽器探測後另一利器處理上述問題。 二、何為特徵嗅探 從前我們都是通過對navigator.userAgent或navigator.appName兩個屬性值進行特定字串匹配和萃取來區分瀏覽器類型和擷取版本號碼的。但隨著IE8提供可選的文檔相容模式設定和各種加殼瀏覽器的出現,導致無法通過navigator.userAgent和navigator.appName的屬性值準確判斷瀏覽器實際提供的API特性和文檔模式,於是就出現特徵嗅探的做法。其實特徵嗅探就是解決兩種問題,第一、是否支援某特性;第二、當前的文檔模式是什麼(注意是文檔模式,不是瀏覽器版本號碼)。 而著名的 var isLteIE8 = !+[1,];就是判斷是否處於IE5678的文檔模式下的特徵嗅探。 三、判斷IE當前的文檔模式 複製代碼// 判斷是否為IEvar isIE = navtigator.userAgent.toLocaleLowerCase().indexOf('msie') !== -1;// 判斷是否為IE5678var isLteIE8 = isIE && !+[1,];// 用於防止因通過IE8+的文檔相容模式設定文檔模式,導致版本判斷失效var dm = document.documentMode, isIE5, isIE6, isIE7, isIE8, isIE9, isIE10, isIE11;if (dm){ isIE5 = dm === 5; isIE6 = dm === 6; isIE7 = dm === 7; isIE8 = dm === 8; isIE9 = dm === 9; isIE10 = dm === 10; isIE11 = dm === 11;}else{ // 判斷是否為IE5,IE5的文字模式為怪異模式(quirks)isIE5 = (isLteIE8 && document.compatMode === 'BackCompat'); // 判斷是否為IE6,IE7開始有XMLHttpRequest對象 isIE6 = isLteIE8 && !isIE5 && !XMLHttpRequest; // 判斷是否為IE7,IE8開始有document.documentMode屬性 isIE7 = isLteIE8 && !isIE6 && !document.documentMode; // 判斷是否IE8 isIE8 = isLteIE8 && document.documentMode; // 判斷IE9,IE10開始支援strict 模式,strict 模式中函數內部this為undefined isIE9 = !isLteIE8 && (function(){ "use strict"; return !!this; }()); // 判斷IE10,IE11開始移除了attachEvent屬性 isIE10 = isIE && !!document.attachEvent && (function(){ "use strict"; return !this; }()); // 判斷IE11 isIE11 = isIE && !document.attachEvent;}複製代碼 注意:若通過IE8+通過指定文檔相容模式的方式,設定為IE6的文檔模式,那麼上述的 var isIE6 = isLteIE8 && !isIE5 && !XMLHttpRequest 將判斷錯誤,因為這時XMLHttpRequest是存在的,這是由於文檔相容模式僅僅是盡量類比舊版本瀏覽器而已,不完全等同於舊版本瀏覽器。所以可直接通過document.documentMode來判斷當前文檔模式。