一 名称: 能力检测/特性检测
二 定义: 即在JavaScript运行时中使用一套简单的检测逻辑,测试浏览器是否支持某种特性
三 最有效的场景:
检测能力是否存在的同时,验证其是否能够展现出预期的行为
四 能力检测的关键
- 检测最常见的方式
function getElement(id){
if(document.getElementById){
return document.getElementById(id); //标准方法
} else if (document.all){
return document.all(id); //IE5之前的版本没有document.getElementById()
} else {
throw new Error("No way to retrive element");
}
}
- 检测切实需要的特性
function getWindowWidth(){
if(document.all){ //document.all存在不意味着浏览器是IE,早期的OPera都支持
return document.documentElement.clientWidth;//不正确的用法
} else {
return window.innerWidth;
}
}
五 安全能力检测
- 能力检测
尽量使用typeof操作符
六 基于能力检测进行浏览器分析
- 检测特性:可以按照能力将浏览器归类
// 检测浏览器是否支持Netscape式的插件
let hasNSPlugins = !!(navigator.plugins && navigator.plugins.length);
- 检测浏览器:可以根据对浏览器特性的检测并与已知特性对比,确认用户使用的是什么浏览器
// 这个类暴露的通用浏览器检测方法使用了检测浏览器范围的能力测试
class BrowserDetector {
constructor() {
// 测试条件编译
// IE6~10 支持
this.isIE_Gte6Lte10 = /*@cc_on!@*/false;
// 测试 documentMode
// IE7~11 支持
this.isIE_Gte7Lte11 = !!document.documentMode;
// 测试 StyleMedia 构造函数
// Edge 20 及以上版本支持
this.isEdge_Gte20 = !!window.StyleMedia;
// 测试 Firefox 专有扩展安装 API
// 所有版本的 Firefox 都支持
this.isFirefox_Gte1 = typeof InstallTrigger !== 'undefined';
// 测试 chrome 对象及其 webstore 属性
// Opera 的某些版本有 window.chrome,但没有 window.chrome.webstore
// 所有版本的 Chrome 都支持
this.isChrome_Gte1 = !!window.chrome && !!window.chrome.webstore;
// Safari 早期版本会给构造函数的标签符追加"Constructor"字样,如:
// window.Element.toString(); // [object ElementConstructor]
// Safari 3~9.1 支持
this.isSafari_Gte3Lte9_1 = /constructor/i.test(window.Element);
// 推送通知 API 暴露在 window 对象上
// 使用默认参数值以避免对 undefined 调用 toString()
// Safari 7.1 及以上版本支持
this.isSafari_Gte7_1 =
(({pushNotification = {}} = {}) =>
pushNotification.toString() == '[object SafariRemoteNotification]'
)(window.safari);
// 测试 addons 属性
// Opera 20 及以上版本支持
this.isOpera_Gte20 = !!window.opr && !!window.opr.addons;
}
isIE() { return this.isIE_Gte6Lte10 || this.isIE_Gte7Lte11; }
isEdge() { return this.isEdge_Gte20 && !this.isIE(); }
isFirefox() { return this.isFirefox_Gte1; }
isChrome() { return this.isChrome_Gte1; }
isSafari() { return this.isSafari_Gte3Lte9_1 || this.isSafari_Gte7_1; }
isOpera() { return this.isOpera_Gte20; }
}
- 能力检测的局限:通过检测一种或一组能力,并不总能确定使用的是哪种浏览器