《编写可维护的 JavaScript》读书笔记第12章:浏览器嗅探

本文介绍了浏览器特性检测的几种方式,包括User-Agent检测、特性检测等,并探讨了这些方法的优劣。文章强调应避免使用特性推断和浏览器推断,推荐采用纯粹的特性检测方法。

1. User-Agent 检测

网景浏览器的 user-agent 字符串如下:

Mozilla/2.0 (Win95; I)

Internet Explorer 浏览器的 user-agent 字符串如下:

Mozilla/2.0 (cmopatible; MSIE 3.0; windows 95)

这使得新生浏览器部分复制现有浏览器用户代理字符串成了一种趋势。

服务器可以获取到浏览器的 user-agent 字符串,客户端通过 JavaScript 的 navigator.userAgent 也可以获取。

// 不好的做法
if (navigator.userAgent.indexOf("MSIE") > -1) {
    // 是 IE
} else {
    // 不是 IE
}

解析 user-agent 字符串并非易事,由于浏览器为了确保其兼容性,都会复制另一个浏览器的用户代理字符串,因此随着每一个新浏览器的出现,用于用户代理检测的代码都需要更新。整个方法长期而言并不具备很好的可维护性。

选择使用用户代理检测,最安全的方法是只检测旧的浏览器

if (isInternetExplorer8OrEarlier) {
    // 处理 IE8 及更早版本
} else {
    // 处理其他浏览器
}

几乎所有的浏览器的 user-agent 都可以被工具修改,因此要尽可能避免检测 user-agent。

2. 特性检测 

特性检测的原理是为特定浏览器的特性进行测试,并仅当特性存在时即可应用特性检测。

// 不好的写法
if (navigator.userAgent.indexOf("MSIE 7") > -1) {
    // 做些什么
}

// 好的写法
if (document.getElementById) {
    // 做些什么
}
// 好的写法
function getById(id) {
    var element = null;
    
    if (document.getElementById) { // DOM
        element = document.getElementById(id);
    } else if (document.all) { // IE
        element = document.all[id];
    } else if (document.layers) { // Netscape <= 4
        element = document.layers[id];
    }
    
    return element;
}

这么使用特性检测是正确和恰当的,因为代码对特性做检测,当特性存在时才使用。

正确检测的顺序:

  • 探测标准的方法

  • 探测不同浏览器的特定方法

  • 均不存在时提供一个合乎逻辑的备用方法

3. 避免特性推断

特性推断尝试使用多个特性但仅验证了其中之一。根据一个特性的存在推断另一个特性是否存在。问题是,推断是假设并非事实,而且可能会导致维护性的问题。

// 不好的写法 - 特性推断
function getById(id) {
    
    var element = null;
    
    if (document.getElementByTagName) { // DOM
        element = document.getElementById(id);
    } else if (window.ActiveXObject) { // IE
        element = document.all[id];
    } else { // Netscape <= 4
        element = document.layers[id];
    }
    
    return element;
}

该函数是最糟糕的特性推断。

4. 避免浏览器推断

// 不好的写法
if (document.all) { // IE
    id = document.uniqueID;
} else {
    id = Math.random();
}

所做的所有探测仅仅说明 document.all 是否存在,而并不能用于判断浏览器是否是 IE。document.all 的存在并不意味着 document.uniqueID 也是可用的。因此这是一个错误的隐式推断,可能会导致代码不能正常运行。

通过特性检测而推断出是某个浏览器同样是很糟糕的做法,这叫做浏览器推断,是一种错误的实践。

5. 应当如何取舍

特性推断和浏览器推断都是糟糕的做法,应当不惜一切代价避免使用。纯粹的特性检测是一种很好的做法。不要试图推断特性间的关系,否则最终得到的结果也是不可靠的。

如果想要使用用户代理嗅探,记住这一点:这么做唯一安全的方式是针对旧的或特定版本的浏览器。而绝不应当针对最新版本或者未来的浏览器。

转载于:https://my.oschina.net/qczhang/blog/187050

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值