zoukankan      html  css  js  c++  java
  • Javascript高级程序设计——客户端检测

         ECMAScript虽然是Javascript的核心,但是要在web中使用Javascript,那么BOM才是核心,BOM为我们提供了操作访问浏览器对象的借口,

    但是由于BOM没有标准规范,导致存在不一致的问题,所以这里需要客户端检测的方法,突破局限。

      先找出设计通用的的方案,然后再使用特定与浏览器的技术增强该方案。

    一、能力检测

      能力检测的目的不是识别浏览器,而是识别浏览器的能力。不必顾及特定的浏览器,只需确定浏览器支持特定的能力。

    //浏览器检测的基本模式
    if(object.property){
        使用object.property
    }
    

      先检测常用的特性,保证了代码最优化。

    //上个例子中的代码利用类型转换来确定某个对象是否存在,但这不能保证该成员是不是想要的。
    这里更可靠的能力检测
    function betterCheck(property){
        return (typeof object.property == "function");
    }
    

     二、怪癖检测

      怪癖检测的目标是识别浏览器的特殊行为。只是检测浏览器的存在缺陷。

    //例如
    早期IE8中,如果实例属性与[[enumerable]]为false的某个原型同名,那么这个属性遍不会被for-in循环枚举。可以通过下面的代码来检测这个”怪癖“
    
    var hasEnumQuirk = function () {
        
        var o = { toString : function () {} };
        for (var pro in o ){
        if(pro == "toString")
            return false;
        }
    
        return true;
    }
    

     怪癖一般都是浏览器所独有的,通常被归为bug,一般仅检测有直接影响的“怪癖”。

    三、用户代理检测

      在浏览器每次发送的http时,都会将userAgent用户代理字符串作为响应首部发送,可以通过navigator.userAgent访问。

      由于经过浏览器大战,现在的浏览器的用户代理都是通过电子欺骗来指定一些误导信息,欺骗服务器。

    1、识别呈现引擎

    //为了减少全局变量,这里使用增强模块模式。在内部声明了浏览器的呈现引擎,浏览器版本和平台信息
    var client = (function () {
     
        //呈现引擎
        var engine = {
             
            ie : 0,
            gecko : 0,
            webkit : 0,
            khtml : 0,
            opera : 0,
     
            ver : null
        };
     
        //浏览器版本
        var broswer = {
             
            ie : 0,
            firefox : 0,
            chrome : 0,
            safari : 0,
            konq : 0,
            opera : 0,
     
            ver : null
        };
     
        //平台信息
        var system = {
             
            win : false,
            mac : false,
            x11 : false,
     
            //移动设备
            iphone : false,
            ipod : false,
            ipad : false,
            ios : false,
            andriod : false,
            nokia : false,
            winMobile : false,
     
            //游戏平台
     
            will : false,
            ps : false
        };
     
     
        //用户代理检测
        var ua = navigator.userAgent;
        //opera会将自己完全伪造成其他浏览器所以先检测它
        if (window.opera){
            engine.opera = broswer.opera = parseInt(engine.ver);
            engine.ver = broswer.ver = window.opera.version();
        }else if (/AppleWebKit/(S+)/.test(ua)){
        //webkit引擎的独有特征是AppleWebKit,利用正则表达式来获取版本号
            engine.ver = RegExp.$1;
            engine.webkit = parseInt(engine.ver);
     
            //确认引擎后可以判断浏览器版本,chrome or safari
            if (/chrome/(S+)/.test(ua)){
                broswer.ver = RegExp.$1;
                broswer.chrome = parseFloat(broswer.ver);
            }else if (/Version/(S+)/.test(ua)){
                broswer.ver = RegExp.$1;
                broswer.safari = parseFloat(broswer.ver);
            }else {
                var safariVersion = 1;
     
                //当判断不出来时,根据引擎版本号来判断浏览器版本
                if (engine.webkit < 100){
                    safariVersion = 1;
                } else if (engine.webkit < 312){
                    safariVersion = 1.2;
                } else if(engine.webkit < 412){
                    safariVersion = 1.3;
                } else{
                    safariVersion = 2;
                }
     
                broswer.ver = broswer.safari = safariVersion;
            }
        } else if (/KHTML/(S+)/.test(ua) || /Konqueror/[^;]+/.test(ua)){
            engine.ver = broswer.ver = RegExp.$1;
            engine.konq = broswer.konq = parseFloat(engine.ver);
        } else if (/rv:([^)]+)) Gecko/d{8}/.test(ua)){
            engine.ver = RegExp.$1;
            engine.gecko = parseInt(engine.ver);
     
            //是否是firefox浏览器
            if (/firefox/(S+)/i.test(ua)){
                broswer.ver = RegExp.$1;
                broswer.firefox = parseFloat(broswer.ver);
            }
            //如果这里没有检测到的firefox岂不是没有浏览器的版本信息了?
        } else if (/MSIE ([^;]+)/.test(ua)){
            engine.ver = broswer.ver = RegExp.$1;
            engine.ie = broswer.ie = parseFloat(engine.ver);
        }
     
        //检测浏览器,不已经检测过了吗?
        broswer.ie = engine.ie;
        broswer.opera = engine.opera;
     
        //检测平台的开始自动判断平台
        var p = navigator.platform;
        system.win = p.indexOf("Win") == 0;
        system.mac = p.indexOf("Mac") == 0;
        system.xll = (p == "X11" || p.indexOf("Linux") == 0);
     
        if (system.win){
            if (/Win(?:dows )?([^do]{2})s?(d+.d+)?/.test(ua)){
                if (RegExp.$1 == "NT"){
                    switch(RegExp.$2){
                        case "5.0":
                            system.win = "2000";
                            break;
     
                        case "5.1":
                            system.win = "xp";
                            break;
     
                        case "6.0":
                            system.win = "Visita";
                            break;
     
                        case "6.1":
                            system.win = "7";
                            break;
     
                        default :
                            system.win = "NT";
                            break;
                    }
                } else if (RegExp.$1 == "9x"){
                    system.win = "ME";
                } else {
                    system.win = RegExp.$1;
                } 
            }
        }
     
        system.iphone = ua.indexOf("iPhone") > -1; 
        system.ipod = ua.indexOf("ipod") > -1; 
        system.ipod = ua.indexOf("ipad") > -1; 
        system.nokia = ua.indexOf("NokiaN") > -1;
     
        //windowMobile
        if (system.win == "CE"){
            system.winMobilem = system.win;
        } else if (system.win == "Ph"){
            if(/Windows Phone OS (d+.d+)/.test(ua)){
                system.win = "Phone";
                system.winMobilem = parseFloat(RegExp.$1);
            }
        }
     
        //ios
        if (system.mac $$ ua.indexOf("Mobile") > -1){
            if (/CPU (?:iPhone ) ?OS (d+.d+)/.test(ua)){
                system.iso = parseFloat(RegExp.$1.replace("_", "."));
            } else {
                system.iso = 2;
            })
        }
     
        //检测安卓
        if (/Andriod (d+ . d+)/.test(ua)){
            system.andriod = parseFloat(RegExp.$1);
        }
     
        system.will = ua.indexOf("Wii") > -1;
        system.ps = /PLAYSTATION/i.test(ua);
     
        return {
            engine : engine,
            broswer : broswer,
            system : system
        };
     
    })();
    

     浏览器检测只是最后一中选择,只要有可能就应该优先采用能力检测和怪癖检测。适用以下三种情形:

    1、不能直接准确的使用能力检测和怪癖检测

    2、浏览器在不同平台下不同的能力,需要检测平台。

    3、跟踪分析等目的需要知道确切的浏览器。

    小结:

    客户端检测时有争议的,由于浏览器之间存在差别,通常需要根据不同浏览器,写不同的代码。客户端检测的常用方法:

    1. 能力检测,在编写代码前,先检测浏览器的能力,把注意集中在浏览器的能力存在上。
    2. 怪癖检测,浏览器中的bug的检测
    3. 用户代理检测,根据用户代理字符串来识别浏览器。

    一般,优先考虑能力检测,怪癖检测时第二选择,引文用户代理检测对用户代理字符串的依赖非常强大

  • 相关阅读:
    Python内置函数 __import__ 动态加载模块
    Django_静态资源配置和ajax(九)
    GO语言学习(五)Go 语言基础语法
    GO语言学习(四)GO语言语言结构
    GO语言学习(三)GO语言学习API文档
    GO语言学习(二)Windows 平台下 LiteIDE 的安装和使用
    GO语言学习(一)Windows 平台下 Go 语言的安装和环境变量设置
    VS无法访问IIS元数据库 您没有足够的特权访问计算机上的IIS网站
    本地存储localStorage以及它的封装接口store.js的使用
    操作类封装
  • 原文地址:https://www.cnblogs.com/yangxunwu1992/p/4785474.html
Copyright © 2011-2022 走看看