JavaScript 特性检测与浏览器嗅探

Internet上充斥着各种操作系统和各种版本的浏览器,每种浏览器都有自己的BOM和独有的特性。因此,保证页面在所有浏览器上正常运行是非常重要的,或者至少可以正常退出,例如显示一个消息建议用户升级浏览器。
有两种方法可以测试浏览器是否可以执行代码:特性检测和浏览器嗅探。它们的最终目标类似,测试给定的浏览器是否执行代码,但它们用于不同的目的。

特性检测

并非所有的浏览器都支持相同的特性,这里的特性是指对于JavaScript开发人员而言可以在代码中访问和使用的特性。特性检测是指检测浏览器是否支持某个给定特性的过程,该方法是浏览器检测的首选方法。使用该方法时,需要做少许的维护工作,所有实现(或不实现)特定特性的浏览器都使用这种方法来检测代码的执行。

特性检测的模式很简单:首先检查特性是否存在,如果存在,就使用该特性。因此,使用一个if语句即可实现,如下所示:

if(navigator.geolocation){
  //user geolocation
}

这段代码将navigator.geolocation用作if语句的条件。在不支持geolocation的浏览器中,navigator.geolocation为undefined,因此值为falsey。

尽管if语句的条件值应被设为true或false,但JavaScript可以将任何值当作true或false。我们称这些值为truthy和falsey。它们并不是真正的布尔值,但用在条件语句中时,其结果就为true或false了。
以下值为falsey:

  • 0
  • ”” (一个空字符串)
  • null
  • undefined
  • [ ] (一个空数组)
  • false
    除了上面的值,其他值都为truthy。
  • 上面的这种方式令人困惑,也给代码增加了歧义性。现在应尽量避免使用truthy/falsey语句,而是选择使用typeof运算符,如下所示:

            if(typeof  navigator.geolocation!="undefined"){
                //use geolocation
            }

    typeof运算符返回一个说明值或对象类型的字符串。在支持geolocation的浏览器中,类型为”object”,而在不支持geolocation其他浏览器中,类型则为”undefined”。

    对于任何对象或值都可以使用typeof运算符。如下表给出了typeof可能返回的值:

    语句结果
    typeof() 1数字number
    typeof() “hello”字符串string
    typeof() true布尔值boolean
    typeof() [](或 任何数组)对象object
    typeof() {}(或 任何对象)对象object
    typeof() undefined未定义undefined
    typeof() null对象object

    ==

            document.write(typeof 1+"<br>");
            document.write(typeof "hello"+"<br>");
            document.write(typeof true+"<br>");
            document.write(typeof [1,2]+"<br>");
            document.write(typeof undefined+"<br>");
            document.write(typeof null+"<br>");

    输出结果为:
    number
    string
    boolean
    object
    undefined
    object

    特性检测方法特别有用,使用该方法可以将支持或不支持特性的浏览器分离开来。浏览器制造商并非都很完美,有时他们发布的浏览器版本具有唯一且古怪的功能。这样,就需要区分单个浏览器,使用特性检测就可以很好地实现这一点。

    浏览器嗅探

    在大多数情况下,首选使用特性检测方法。浏览器嗅探方法具有许多缺陷,其中之一就是少数浏览器可能宣称自己是某主流浏览器,其实并不是那种浏览器类型。另外一个问题是浏览器嗅探依赖于浏览器的userAgent字符串(user-agent string),该字符串用于标识浏览器,且浏览器制造商可以在不同的版本之间进行大幅度的修改。仅挡针对其有古怪行为的单个浏览器时,才使用浏览器嗅探技术。
    navigator对象的appName属性和userAgent属性在标识浏览器方面很有用。appName属性将返回浏览器的模型,如对IE返回Microsoft Internet Explorer,对Firefox,Chrome和Safari返回Netscape。
    userAgent属性返回一个包含多段信息的字符串,如浏览器的版本,操作系统和浏览器模型。但是,这个属性的返回值因浏览器而异。例如,浏览器的版本被嵌入在该字符串的不同位置。

    例如在chrome获取userAgent字符串:
    Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.87 Safari/537.36

    从这个字符串中可以得知使用的是windows10 64位操作系统,Chrome 54.0版本的浏览器。AppleWebKit好像是浏览器内核。后续的操作获取浏览器信息都是根据这个字符串来进行的。

    例如:

        <script>
            function getBrowserName(){
                var browser=navigator.userAgent;
                if(browser.indexOf("MSIE")>=0){
                    return "MSIE";
                }else if(browser.indexOf("Firefox")>=0){
                    return "Firefox";
                }else if(browser.indexOf("Chrome")>=0){
                    return "Chrome";
                }else if(browser.indexOf("Safari")>=0){
                    return "Safari";
                }else if(browser.indexOf("Opera")>=0){
                    return "Opera";
                }else{
                    return "UNKNOWN";
                }
            }
    
            function getBrowerVersion() {
                var ua=navigator.userAgent;
                var browser=getBrowserName();
                var findIndex=ua.indexOf(browser)+browser.length+1;
                var browserVersion=parseFloat(ua.substring(findIndex,findIndex+3));
                return browserVersion;
            }
    
            var browserName=getBrowserName();
            var browserVersion=getBrowerVersion();
    
            document.write(browserName+"  "+browserVersion);
        </script>

    在Chrome中输出:
    Chrome 54
    在Opear中输出:
    Chrome 55
    在Firefox中输出:
    Firefox 50

    通过使用indexOf来搜索检测是否存在某些关键字,如MSIE或者Firefox,通常就可以确定浏览器的名称。只需要观察navifator.userAgent返回的字符串,查找浏览器名称或者唯一标识浏览器的子串。在userAgent字符串中,浏览器的版本信息通常紧跟在浏览器名称之后。有了浏览器的名称和版本信息,就可以利用这些信息过滤用户当前运行的浏览器,从而来检测判断该浏览器是否具有某种特性。
    注意:除针对单个浏览器外,不能依赖于浏览器嗅探技术。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值