//能力检测的目标不是识别特定的浏览器,而是识别浏览器的能力,只要确定浏览器支持该能力,就可以给出解决方案
例如:对于有些并不是每个浏览器实现的方法,你需要检测先检测该浏览器是否支持该方法
/**
* IE5.0之前的版本不支持document.getElementById()这个dom方法
* IE5.0之前可以使用非标准的document.all来实现相同的目的
* 于是也就出现了下面的能力检测代码
* @param id
*/
function getElement(id) {
//先检测通过id获取指定元素的标准方式,如果该函数存在就是用该函数
if (document.getElementById) {
return document.getElementById(id);
//否则继续检测document.all,如果是则用它
} else if (document.all) {
return document.all[id];
} else {
throw new Error("No way to retrieve element!");
}
}
/**
* 检测某个属性是否存在并不能确定是否支持排序 像 {sort:true}这个对象也会在这个方法里返回true
* @param object
*/
function isSortable(object) {
return !!object.sort;
}
//更好的方式是检测sort是否是一个函数
function isSortable(object) {
//在可能的情况下,要尽量使用typeof进行能力检测
return typeof object.sort == "function";
}
function hasCreateElement() {
//在可能的情况下,要尽量使用typeof进行能力检测
///但在IE8及之前的版本这个函数返回false因为typeof document.createElement返回的是'object'而不是function
//DOM对象是宿主对象,IE及更早的版本中的宿主是通过COM而非JScript实现的,因此document.createElement函数确实是一个COM对象,所以typeof返回'object'
//IE9纠正了这个问题,对所有DOM方法都返回'function'
return typeof document.createElement == "function";
}
//关于typeof的行为不标准,IE中还可以举出例子来:
//ActiveX对象(只有IE支持)与其他对象的差异很大
//例如不使用typeof测试某个属性会导致报错
var xhr = new ActiveXObject("Microsoft.XMLHttp");
//if (xhr.open) {//如果这样使用,会发生错误。像这样直接把函数当作属性访问会导致javascript错误
//执行操作。
//}
/**
* 在浏览器环境下测试任何对象的某个特性是否存在要使用下面的方法
* 目前使用isHostMethod()方法还是比较可靠的
* 但是宿主对象没有义务保持目前的实现方式不变,所以这个函数不保证永远可靠
* @param object
* @param property
*/
function isHostMethod(object, property) {
var t = typeof object[property];
return t == 'function' ||
//检测IE8及之前的版本DOM对象
(!!(t == 'object' && object[property])) ||
//检测ActiveXObject, 它的 typeof xhr.open 会返回unknown
t == 'unknown';
}
var result = isHostMethod(xhr, 'open');
alert(result);
能力检测并不是浏览器检测
//在实际开发中,应该将能力检测作为确定下一步解决方案的依据,而不是用它来判断用户使用的是什么浏览器
//检测某个或某几个特性并不能够确定是哪个浏览器
//错误,不够具体,因为后来的safari也实现了这两个属性,所以这段代码就不能够准确的判断是firefox还是safari了
var isFirefox = !!(navigator.vendor && navigator.vendorSub);
//这个相当于假设IE将来的版本仍然会继续存在这两个属性,同时还假设其他浏览器不会实现这两个属性
var isIE = !!(document.all && document.uniqueID);
//实际上根据浏览器将能力组合起来是更可取的方式,如果你知道你的应用程序需要使用某种特定的浏览器特性那么最好是一次性检测所有的相关特性,而不是要分别检测
//确定浏览器是否支持Netscape风格的插件
var hasNSPlugins = !!(navigator.plugins && navigator.plugins.length);
//确定浏览器是否具有DOM1级规定的能力
var hasDOM1 = !!(document.getElementById && document.createElement && document.getElementsByTagName)