不要使用浏览器嗅探,尽量使用特性检测和特性模拟
平淡的描述
在js中,能使用特征监测就尽量不要使用浏览器嗅探。嗅探浏览器目的是判断可否使用这个对象或者API,但是抛开浏览器
的各个版本的userAgent不说,还有些浏览器打补丁的情况,造成判断异常复杂,兜了个大的圈子,而特征检测则是直接
了当,不存在维护困难的问题。
其次,当不确定某个版本的浏览器是否有特殊的bug时(如IE8下js访问css的float属性时,是styleFloat,
而在w3c浏览器下是CssFloat;IE8下getElementByTagNames返回NodeList包括注释节点),仅仅使用特征检测却是不够的。
这是就需要特性模拟。特性模拟最经典的例子就是jQuery的support模块,我们可以参考该模块来充分认识各个浏览器下的独特
的bug。
示范1
利用特征监测来推测IE的的版本号非常好用,也可利用IE的一些特有对象来识别IE所有系列。
'VBArray' in window // true 'ActiveXObject' in window //true if(isIE){ if(document.documentMode == 11){ isIE11 = true; }else if('WebSocket' in window){ isIE10 = true; }else if('HTMLElement' in window){ isIE9 = true; }else if('localStorage' in window){ isIE8 = true; } else if('minHeight' in div.currentStyle){ isIE7 = true; } else{ isIE6 = true; document.execCommad('backgroundimagecache',false,false); //IE6并不会对背景图片进行缓存,故进行修补 } }
对于ff:
经最新版本测试
'netscape' in window // true
示范2
利用特性模拟来判断浏览器的getElementByTagNames返回的NodeList对象是否包含注释节点:
(function(){ var hasCommentNode = false,d; d = document.createElement("div"); d.appendChild(document.createComment("test")); if(d.getElementByTagNames("*").length != 0) hasCommentNode = true; window.hasCommentNode = hasCommentNode ;
d.outerHTML = ""; })()
模拟的结果保存在全局变量上,以供后面的代码使用。
更为详细的特征模拟可以参考jQuery的support模块。其主要模拟了
- NodeList对象在旧版IE(IE678)下使用数组方法slice会出错;
- CssStyleDeclaration的float的属性名问题;
- IE下的滤镜问题(针对透明度而言);
- 旧版IE下setAttribute("className")问题;
言论
可见,没必要再对userAgent耿耿于怀,字符串可以随意伪造,但是浏览器的相关特性却是不会改变,所以我们
还是宁愿花几毫秒来测试一番,而不用提心吊胆的根据字符串随意猜测相关特性。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了