用JS识别各版本浏览器
自昨天发了各浏览器内核介绍的随笔,就闲不住了,想直接写个JS来识别用户所用浏览器版本。
写着写着却发现很多坑爹的地方,比如IE10-的版本是依循常规支持attachEvent,但到了IE11,却只支持addEventListener而不再支持attachEvent。光是这一点就可以判断IE是个大坑,IE11的存在可能会导致之前你写过的代码出现错乱。另如原本可用
var ieVersion = eval("''+/*@cc_on"+" @_jscript_version@*/-0")*1
的嗅探脚本来判断是否IE,如果值非0则表示为IE浏览器,但到了IE11,也直接返回0了(即IE11不再识别@cc_on这个IE独有的条件编译语句)。。。。
还有就是上篇文章提到的Opera自从去年就抛弃了自家的Presto内核,转而跟进使用Chrome内核,导致的结果是,新版Opera不再支持window.opera,而且跟随Chrome浏览器支持window.chrome等系列Chrome特性,就连userAgent字样也去了“opera”并直接套用Chromium/Blink内核的userAgent信息(好事是在尾部还是保留了一句OPR/XX.0)
不过琢磨琢磨,问题总会得到解决的。首先解决下比较容易解决的Firefox,其userAgent信息如下:
对比其它浏览器内核的ua信息它独有“Firefox/XX.0”字样,故我们可以这样判断:
rFirefox = /(firefox)\/([\w.]+)/;
matchBS = rFirefox.exec(ua);
if ((matchBS != null)&&(!(window.attachEvent))&&(!(window.chrome))&&(!(window.opera))) {
//codes...
}
这里还判断了是否支持window.attachEvent 和 window.chrome、window.opera事件,是为了防止其它非Firefox浏览器的伪装ua信息,但我承认这点很难做到尽善尽美。
接着是Safari,虽然Safari的ua信息含有safari字样,但由于谷歌的浏览器是苹果浏览器内核WebKit的分支,导致Chrome的ua信息也含有safari字样:
这种情况只能“找不同”了,可以看到Safari的ua信息在“Safari/...”之前连着一个“Version/...”,而Chrome的ua信息是没有的,所以可以这样写:
rSafari = /version\/([\w.]+).*(safari)/;
matchBS = rSafari.exec(ua);
if ((matchBS != null)&&(!(window.attachEvent))&&(!(window.chrome))&&(!(window.opera))) {
//....
}
接着说Chrome和Opera,这里比较头疼的一点。。。。是Chrome的好基友Opera也开始使用了Chromium或Blink引擎,导致二者ua信息以及对BOM的支持几乎一致(这不废话么,内核都一样了),但还是可以从ua找不同:
于是我们可以这样写(注意Opera也要兼顾旧版本,也就是使用Presto内核的情况):
rOpera = /(opera).+version\/([\w.]+)/;
rNewOpera = /(opr)\/(.+)/;
rChrome = /(chrome)\/([\w.]+)/;
matchBS = rOpera.exec(ua);
if ((matchBS != null)&&(!(window.attachEvent))) { //旧Opera识别
return { browser : matchBS[1] || "", version : matchBS[2] || "0" };
}
matchBS = rChrome.exec(ua);
if ((matchBS != null)&&(!!(window.chrome))&&(!(window.attachEvent))) { //Chrome识别
matchBS2 = rNewOpera.exec(ua);
if(matchBS2 == null) //新Opera识别
return { browser : matchBS[1] || "", version : matchBS[2] || "0" };
else
return { browser : "Opera", version : matchBS2[2] || "0" };
}
最后说下IE的识别吧,IE是个大坑(红框部分是建议用于判断的地方):
由上图可知,IE6/7从MSIE版本号直接判断即可,从IE8开始多了个Trident信息,则IE8-IE11只需判断Trident版本号。那么我们就可以自行写两个判断,先判断是否IE——即ua信息是否包含了MSIE信息或者Trident信息(注意IE11已经移除了MSIE信息),接着再判断是否IE7-或者IE8+ :
rMsie = /(msie\s|trident\/7)([\w.]+)/;
rTrident = /(trident)\/([\w.]+)/;
matchBS = rMsie.exec(ua);
if (matchBS != null) {
matchBS2 = rTrident.exec(ua);
if (matchBS2 != null){
switch (matchBS2[2]){
case "4.0": return { browser : "IE", version : "8" };break;
case "5.0": return { browser : "IE", version : "9" };break;
case "6.0": return { browser : "IE", version : "10" };break;
case "7.0": return { browser : "IE", version : "11" };break;
default:return { browser : "IE", version : "undefined" };
}
}
else
return { browser : "IE", version : matchBS[2] || "0" };
}
下面贴下全部代码,可供参考:
<script type="text/javascript">
var userAgent = navigator.userAgent,
rMsie = /(msie\s|trident\/7)([\w.]+)/,
rTrident = /(trident)\/([\w.]+)/,
rFirefox = /(firefox)\/([\w.]+)/,
rOpera = /(opera).+version\/([\w.]+)/,
rNewOpera = /(opr)\/(.+)/,
rChrome = /(chrome)\/([\w.]+)/,
rSafari = /version\/([\w.]+).*(safari)/;
var matchBS,matchBS2;
var browser;
var version;
var ua = userAgent.toLowerCase();
var uaMatch = function(ua) {
matchBS = rMsie.exec(ua);
if (matchBS != null) {
matchBS2 = rTrident.exec(ua);
if (matchBS2 != null){
switch (matchBS2[2]){
case "4.0": return { browser : "IE", version : "8" };break;
case "5.0": return { browser : "IE", version : "9" };break;
case "6.0": return { browser : "IE", version : "10" };break;
case "7.0": return { browser : "IE", version : "11" };break;
default:return { browser : "IE", version : "undefined" };
}
}
else
return { browser : "IE", version : matchBS[2] || "0" };
}
matchBS = rFirefox.exec(ua);
if ((matchBS != null)&&(!(window.attachEvent))&&(!(window.chrome))&&(!(window.opera))) {
return { browser : matchBS[1] || "", version : matchBS[2] || "0" };
}
matchBS = rOpera.exec(ua);
if ((matchBS != null)&&(!(window.attachEvent))) {
return { browser : matchBS[1] || "", version : matchBS[2] || "0" };
}
matchBS = rChrome.exec(ua);
if ((matchBS != null)&&(!!(window.chrome))&&(!(window.attachEvent))) {
matchBS2 = rNewOpera.exec(ua);
if(matchBS2 == null)
return { browser : matchBS[1] || "", version : matchBS[2] || "0" };
else
return { browser : "Opera", version : matchBS2[2] || "0" };
}
matchBS = rSafari.exec(ua);
if ((matchBS != null)&&(!(window.attachEvent))&&(!(window.chrome))&&(!(window.opera))) {
return { browser : matchBS[2] || "", version : matchBS[1] || "0" };
}
if (matchBS != null) {
return { browser : "undefined", version : " browser" };
}
}
var browserMatch = uaMatch(userAgent.toLowerCase());
if (browserMatch.browser) {
browser = browserMatch.browser;
version = browserMatch.version;
}
document.write(browser+version);
</script>
不过还是得说,识别各种版本的浏览器是项非常麻烦的事情,以上代码能帮你顺利应付大部分的情况,但如果遇到某些特殊情景(比如浏览器伪装ua信息),就无法识别浏览器具体版本了。
欢迎交流和探讨~
用JS识别各版本浏览器的更多相关文章
- 用js识别是否360浏览器
360浏览器说实话比较恶,以前可以通过内核返回的字符串判定是否包含"360"字样的方法来判定 如以下代码 window.navigator.userAgent.indexOf('3 ...
- 浏览器兼容处理(HTML条件注释、CSSHack和JS识别)
前面的话 本文中所有IEx+代表包含x及x以上:IEx-代表包含x及x以下,仅个人习惯.例:IE7+代表IE7.IE8…… 本文中所有例子全部经过测试,欢迎交流. HTML识别 条件注释法(IE10+ ...
- 轮播图采用js、jquery实现无缝滚动和非无缝滚动的四种案例实现,兼容ie低版本浏览器
项目源代码下载地址:轮播图 以下为项目实现效果:(由于gif太大,所以只上传一张图片,但效果完全能实现,经测试,在ie各版本浏览器及chrome,firefox等浏览器中均能实现效果,可以实现点击切换 ...
- JS判断不同的浏览器,不同的浏览器版本
JS判断不同的浏览器,不同的浏览器版本
- Js获取操作系统版本 && 获得浏览器版本
//利用原生Js获取操作系统版本function getOS() { var sUserAgent = navigator.userAgent; var isWin = (navigator.plat ...
- Html5shiv ---- 让IE低版本浏览器识别并支持HTML5标签
Html5shiv.js是针对IE浏览器的 javaScript 补丁,作用如题 该脚本的下载链接 使用使在head标签中使用script标签引用即可
- 使用html5兼容低版本浏览器
因为html5 新出的一些语义化的标签,在低版本浏览器下不能识别,举个例子,比如你写了一个 header 标签中,写了一段文本,在低版本浏览器下,肯定是能看到的,但是,那是他是不认识 header标签 ...
- 低版本浏览器支持HTML5标签的方法
最近刷了一道面试题,是关于低版本浏览器支持HTM5标签的写法,在网上找了一些,都行之有效,但是缺少整体总结,所以在这里总结一下,方便其他人过来阅读. IE低版本需要支持HTML5标签: 方法1.传统引 ...
- Bootstrap 4/3 页面基础模板 与 兼容旧版本浏览器
Bootstrap 3 与 4 差别很大,目录文件结构.所引入的内容也不同,这里说说一下 Bootstrap 引入的文件.网页模板和兼容性问题.本网站刚刚搭建好,正好发一下文章原来测试网站. Boot ...
随机推荐
- POJ 2135 Farm Tour 最小费用流
两条路不能有重边,既每条边的容量是1.求流量为2的最小费用即可. //#pragma comment(linker, "/STACK:1024000000,1024000000") ...
- 《Linux 多线程服务端编程:使用 muduo C++ 网络库》电子版上市
<Linux 多线程服务端编程:使用 muduo C++ 网络库> 电子版已在京东和亚马逊上市销售. 京东购买地址:http://e.jd.com/30149978.html 亚马逊Kin ...
- PHP中phar包的使用
PHP5.3之后支持了类似Java的jar包,名为phar.用来将多个PHP文件打包为一个文件. 首先需要修改php.ini配置将phar的readonly关闭,默认是不能写phar包的,includ ...
- HTML5 CSS3学习
HTML5 CSS3学习 :http://www.1000zhu.com/course/css3/ HTML5 相关书籍: http://www.html5cn.com.cn/news/gdt/2 ...
- aa5
var placeList = [ {name:'海门', geoCoord:[121.15, 31.89]}, {name:'鄂尔多斯', geoCoord:[109.781327, 39.6082 ...
- Android Webview 调用JS跳转到指定activity
JAVA: WebView wv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(save ...
- Maemo平台上如何使用Openvpn
Maemo是一个开源的智能手机软件平台社区,它是基于Debia的LInux发行版本,Maemo的大多是开源的,并已经制定了Maemo和诺基亚内部的设备与许多开源项目,例如,Debian的Linux内核 ...
- 配置Chrome Driver
书中使用Firefox driver出现莫名问题,大概是firefox的版本太新了,懒得降级处理,故学习配置Chome driver进行测试. 1.到http://chromedriver.stora ...
- 如何让你的UWP应用程序无缝调用几何作图
有时候需要编辑一些几何图形,如三角形,圆锥曲线等,在UWP应用中加入这些几何作图功能是件费时间又很难做好的事.其实Windows 10 应用商店中已有一些专业的几何作图工具了,那么能借来一用吗?答案是 ...
- python核心编程(第二版)习题
重新再看一遍python核心编程,把后面的习题都做一下.