第九章客戶端檢測
客戶端檢測
9.1能力檢測
只要確定瀏覽器支持特定的能力,就能給出解決方案
if(object.propertyInQuestion){
}
兩個概念:先檢測達成目的的最常用的特性;檢測實際要用到的特性
9.1.1更可靠的能力檢測
盡可能使用typeof進行能力檢測
在瀏覽器環境測試任何對象的某個特性是否存在使用如下函數:
function isHostMethod(object, property) {
var t = typeof object[property];
return t == ‘function‘ ||
(!!(t == ‘object‘ && object[property])) ||
t == ‘unknown‘;
}
result = isHostMethod(xhr, "open"); //true
result = isHostMethod(xhr, "foo"); //false
9.1.2能力檢測不是瀏覽器檢測
最好是一次性檢測所有相關特性,而不是分別檢測
//確定瀏覽器是否支持 Netscape 風格的插件
var hasNSPlugins = !!(navigator.plugins && navigator.plugins.length );
//確定瀏覽器是否具有 DOM1 級規定的能力
var hasDOM1 = !!(document.getElementById && document.createElement
&& document.getElementByTagName);
9.2怪癖檢測
識別瀏覽器的特殊行為,知道瀏覽器存在的缺陷
9.3用戶代理檢測
通過檢測用戶代理字符串(可通過javascript的navigator.userAgent 屬性訪問)來確定實際使用的瀏覽器;在服務器端,是一種常用而且廣為接受的做法。在客戶端,優先級排在能力檢測和怪癖檢測之後。
9.3.1用戶代理字符串的歷史
瀏覽器應該發送簡短的用戶代理字符串,指明瀏覽器的名稱和版本號,字符串格式:標識符/產品版本號
9.3.2用戶代理字符串檢測技術
1.識別呈現引擎
腳本主要檢測五大呈現引擎: IE、Gecko、WebKit、KHTML 和 Opera。
使用模塊增強模式來封裝檢測腳本
var client = function(){
//呈現引擎
var engine = {
ie : 0,
gecko : 0,
webkit : 0,
khtml : 0,
opera : 0,
//具體的版本號
ver : null
};
//再次檢測呈現引擎、平臺和設備
return {
engine : engine
};
}();
如果檢測到那個呈現引擎,就以浮點數值形式將該引擎的版本號寫入相應的屬性。而呈現引擎的完整版本是一個字符串,則被寫入ver屬性。
if(client.engine.ie){ //如果是IE ,engine.ie的值應大於0
//針對IE
} else if (client.engine.gecko > 1.5) {
if(client.engine.ver == "1.8.1"){
//to-do
}
}
正確的識別呈現引擎關鍵是檢測順序要正確(以下為檢測順序)
1. Opera
//Opera 5起支持window.opera對象
if ( window.opera ){
engine.ver = window.opera.version(); //Opera 7.6起返回瀏覽器版本字符串
engine.opera = parseFloat( engine.ver );
}
2. WebKit
//AppleWebKit獨一無二
var ua = navigator.userAgent;
if ( window.opera ){
engine.ver = window.opera.version();
engine.opera = parseFloat( engine.ver );
} else if ( /AppleWebKit\/(\S+)/.test(ua)){
engine.ver = RegExp["$1"];
engine.webkit = parseFloat(engine.ver);
}
3. KHTML
var ua = navigator.userAgent;
if ( window.opera ){
engine.ver = window.opera.version();
engine.opera = parseFloat( engine.ver );
} else if ( /AppleWebKit\/(\S+)/.test(ua)){
engine.ver = RegExp["$1"];
engine.webkit = parseFloat(engine.ver);
} else if ( /KHTML\/(\S+)/.test(ua) || /Konqueror\/([^;]+)/.test(ua)){
engine.ver = RegExp["$1"];
engine.khtml = parseFloat(engine.ver);
}
4. Gecko
Gecko的版本號位於字符串“rv:”與一個閉括號之間,還要查找“Gecko/”後的8個數字
var ua = navigator.userAgent;
if ( window.opera ){
engine.ver = window.opera.version();
engine.opera = parseFloat( engine.ver );
} else if ( /AppleWebKit\/(\S+)/.test(ua)){
engine.ver = RegExp["$1"];
engine.webkit = parseFloat(engine.ver);
} else if ( /KHTML\/(\S+)/.test(ua) || /Konqueror\/([^;]+)/.test(ua)){
engine.ver = RegExp["$1"];
engine.khtml = parseFloat(engine.ver);
} else if ( /rv:([^\)]+)\) Gecko\/\d{8}/.test(ua)){
engine.ver = RegExp["$1"];
engine.gecko = parseFloat(engine.ver);
}
5.IE
var ua = navigator.userAgent;
if ( window.opera ){
engine.ver = window.opera.version();
engine.opera = parseFloat( engine.ver );
} else if ( /AppleWebKit\/(\S+)/.test(ua)){
engine.ver = RegExp["$1"];
engine.webkit = parseFloat(engine.ver);
} else if ( /KHTML\/(\S+)/.test(ua) || /Konqueror\/([^;]+)/.test(ua)){
engine.ver = RegExp["$1"];
engine.khtml = parseFloat(engine.ver);
} else if ( /rv:([^\)]+)\) Gecko\/\d{8}/.test(ua)){
engine.ver = RegExp["$1"];
engine.gecko = parseFloat(engine.ver);
} else if (/MSIE ([^;]+)/.test(ua)){
engine.ver = browser.ver = RegExp["$1"];
engine.ie = browser.ie = parseFloat(engine.ver);
}
2.識別瀏覽器
相同內核的瀏覽器的JavaScript有可能引擎不一樣
var client = function(){
//呈現引擎
var engine = {
ie : 0,
gecko : 0,
webkit : 0,
khtml : 0,
opera : 0,
//具體的版本號
ver : null
};
var browser = {
//瀏覽器
ie : 0,
firefox : 0,
konq : 0,
opera : 0,
chrome : 0,
safari : 0,
//具體的版本
ver : null
};
//再次檢測呈現引擎、平臺和設備
return {
engine : engine,
browser : browser
};
}();
大多數瀏覽器與其呈現引擎密切相關,所以下面示例中檢測瀏覽器的代碼與呈現引擎的代碼是混合在一起的
//檢測呈現引擎及瀏覽器
var ua = navigator.userAgent;
if ( window.opera ){
engine.ver = window.opera.version();
engine.opera = parseFloat( engine.ver );
} else if ( /AppleWebKit\/(\S+)/.test(ua)){
engine.ver = RegExp["$1"];
engine.webkit = parseFloat(engine.ver);
//確定是Chrome 還是 Safari
if ( /Chrome\/(\S+)/.test(ua)){
browser.ver = RegExp["$1"];
browser.chrome = parseFloat(browser.ver);
} else if ( /Version\/(S+)/test(ua)){
browser.ver = RegExp["$1"];
borwser.safari = parseFloat(browser.ver);
} else {
//近似的確定版本號
var safariVersion = 1;
if (engine.webkit < 100 ){
safariVersion = 1;
} else if (engine.webkit < 312){
safariVersoin = 1.2;
} else if (engine.webkit < 412){
safariVersion = 1.3;
} else {
safariVersion = 2;
}
browser.safari = browser.ver = safariVersion;
}
} else if ( /KHTML\/(\S+)/.test(ua) || /Konqueror\/([^;]+)/.test(ua)){
engine.ver = RegExp["$1"];
engine.khtml = parseFloat(engine.ver);
} else if ( /rv:([^\)]+)\) Gecko\/\d{8}/.test(ua)){
engine.ver = RegExp["$1"];
engine.gecko = parseFloat(engine.ver);
//確定不是Firefox
if( /Firefox\/(\S+)/.test(ua)){
browser.ver = RegExp["$1"];
browser.firefox = parseFloat(browser.ver);
}
} else if (/MSIE ([^;]+)/.test(ua)){
engine.ver = browser.ver = RegExp["$1"];
engine.ie=browser.ie=parseFloat(engine.ver);
}
if(client.engine.webkit){
if (client.browser.chrome) {
}else if (client.browser.safari){
}
} else if (client.engine.gecko) {
if (client.browser.firefox) {
}else{
}
}
3.識別平臺在各種平臺版本的瀏覽器,在不同的平臺下可能會有不同的問題
var client = function(){
//呈現引擎
var engine = {
ie : 0,
gecko : 0,
webkit : 0,
khtml : 0,
opera : 0,
//具體的版本號
ver : null
};
var browser = {
//瀏覽器
ie : 0,
firefox : 0,
konq : 0,
opera : 0,
chrome : 0,
safari : 0,
//具體的版本
ver : null
};
var system = {
win : false,
mac : false,
xll : false
};
//再次檢測呈現引擎、平臺和設備
return {
engine : engine,
browser : browser,
system : system
};
}();
//navigator.platform值Win32 、Win64、MacPPC、MacIntel、X11、Linux i686
var p = navigator.platform;
system.win = p.indexOf("Win") == 0;
systemp.mac = p.indexOf("Mac") == 0;
system.xll = (p.indexOf("Xll")) == 1 || (p.indexOf("Linux") == 0);
後見9.3.9完整代碼
第九章客戶端檢測