zoukankan      html  css  js  c++  java
  • 用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 = /(msies|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 = /(msies|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>
    View Code


    不过还是得说,识别各种版本的浏览器是项非常麻烦的事情,以上代码能帮你顺利应付大部分的情况,但如果遇到某些特殊情景(比如浏览器伪装ua信息),就无法识别浏览器具体版本了。

    欢迎交流和探讨~

    donate

  • 相关阅读:
    jsonrpc
    第十章:多线程
    第九章:IO流
    第八章:集合
    第七章:常用类
    第六章:异常机制
    第四章:数组
    第三章:流程控制语句
    第二章:数据类型和运算符
    第五章:面向对象4
  • 原文地址:https://www.cnblogs.com/vajoy/p/3736576.html
Copyright © 2011-2022 走看看