一、前言
苦逼的前端攻城獅都深受瀏覽器兼容之苦,再完成每一項功能前都要左顧右盼,生怕瀏覽器不支持某個API,生怕原生API內含臭蟲因此判斷瀏覽器類型和版本號成了不可繞過的一道關卡,而特征嗅探是繼瀏覽器探測后另一利器處理上述問題。
二、何為特征嗅探
從前我們都是通過對navigator.userAgent或navigator.appVersion兩個屬性值進行特定字符串匹配和萃取來區分瀏覽器類型和獲取版本號的。但隨著IE8提供可選的文檔兼容性模式設置和各種加殼瀏覽器的出現,導致無法通過navigator.userAgent和navigator.appVersion的屬性值準確判斷瀏覽器實際提供的API特性和文檔模式,于是就出現特征嗅探的做法。其實特征嗅探就是解決兩種問題,第一、是否支持某特性;第二、當前的文檔模式是什么(注意是文檔模式,不是瀏覽器版本號)。
而著名的 var isLteIE8 = !+[1,];就是判斷是否處于IE5678的文檔模式下的特征嗅探。
三、判斷IE當前的文檔模式
// 判斷是否為IE var isIE = navtigator.userAgent.toLocaleLowerCase().indexOf('msie') !== -1;
// 判斷是否為IE5678
var 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),真實的IE5.5瀏覽器中沒有document.compatMode屬性 isIE5 = (isLteIE8 && (!document.compatMode || 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開始支持嚴格模式,嚴格模式中函數內部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來判斷當前文檔模式。
四、總結
由于本篇重在代碼實現上,結合《JS魔法堂:瀏覽器模式和文本模式怎么玩?》也許會更易理解本篇內容。
尊重原創,轉載請注明來自:http://www.cnblogs.com/fsjohnhuang/p/3818947.html,^_^肥仔John
文章列表