《JS高程(3)》客户端检测-第9章笔记(10)
来源:互联网 发布:小米note查看网络制式 编辑:程序博客网 时间:2024/06/07 18:07
- 使用能力检测
- 用户代理监测的历史
选择检测方式
因各个浏览器之间不一致性,不得不采用各种客户端检测方法
能力检测
检测目的:识别浏览器的能力。
if(object.propertyInQuestion){ //使用object.propertyInQuestion}
注
先检测达成目的的最常用的性能,保证代码的优化;
必须测试实际用到的特性。
更靠谱的能力检测
通过typeof
确定是否为函数,进行能力检测。
// 检查sort是不是函数function isSortable(object){ return typeof object.sort == "function";}
typeof
操作符用于确定sort
的却是函数,因此可以调用他对数据进行排序。
在可能的情况下,尽量使用typeof
进行能力检测。特别是宿主对象没有义务让typeof
返回合理值。
能力检测,不是浏览器检测
检测一个或几个特性并不能确定浏览器;
根据浏览器的不同将能力组合起来,一次性检测所有相关的特性,而不是分次检测。
//确定浏览器是否支持Netspace风格的插件var hasNSPlugins = !!(navigator.plugins && navigator.pligins.length);//确定浏览器是否具有DOM1级别规定的能力var hasDOM1 = !!(document.getElementById && document.createElement && document.getElementByTagName);
在得到布尔值后继续使用,从而节省重新检测能力的时间。
怪癖检测
目标:识别浏览器的特殊行为,知道浏览器存在什么缺陷.
“怪癖”即为bug。
var hasDontEnumQuik = function(){ var o = {toString : function(){}}; for(var props in o){ if (props == "toString"){ return false ; } } return true;}();
通过一个匿名函数来测试该’怪癖’,函数中创建了衣蛾带有toString()方法的对象。在正确的ECMAScript实现中,toString应该在for-in循环中作为属性返回。
‘怪癖’的检测应在脚本开始时,尽早解决问题。
IE8及更早版本中存在一个bug,即如果某个实例属性与[[Enumerable]]标记为false的某个原型属性同名,那么该实例属性将不会出现在for—in循环当中;
Safari 3以前版本会枚举被隐藏的属性;
cloneNode()方法不会复制添加到DOM节点中的javascript属性,例如事件处理程序等,IE在此存在一个bug,即它会复制事件处理程序;
IE8及更早版本与其他浏览器处理空白字符的方式不一样,IE9之前的版本不会为空白符创建节点;
IE8及较低版本不区分ID的大小写,如果页面中多个元素的的ID值相同,getElementById()只返回文档中第一次出现的元素;
IE7及以下版本有一个有意思的怪癖:name特性与给定ID匹配的表单元素(
<input>,<textarea>,<button>及<select>
)也会被该方法返回- IE7以前,通过getAttribute()方法访问style特性(返回一个对象)或者onclick这样的事件处理 特性时(返回一个函数),返回的值与属性的值相同,同时setAttribute()存在一些异常行为。通过这个方法设置的class和style特性,没有任何效果,设置事件处理程序特性是也一样。
用户代理检测
争议最大的客户端检测技术。
通过检测用户代理字符串确定实际使用的浏览器。
编写脚本的五大呈现引擎:IE , Gecko , Webkit , KHTML , Opera.
var client = function(){ var engine = { // 呈现引擎 ie:0, gecko:0, webkit:0, khtml:0, opera:0, //具体的版本号 ver:null }; //在此检验呈现引擎、平台和设备 return { engine:engine };}();
声明一个名为client的全局变量,保存相关信息。匿名函数内部定义了一个局部变量engine,包含默认设置的对象字面量,每个呈现引擎都对应一个属性,属性值默认为0,如果检测到了某个引擎的版本号,就以浮点数的形式将该引擎的版本号写入相应的属性。而呈现引擎的完整版本(是一个字符串),则被写入ver属性。
if(client.engine.ie){//如果是IE,client.ie的值应该大于0//针对IE代码}else if (client.engine.gecko > 1.5){ if (client.engine.ver == "1.8.1"){ //针对这个版本执行某些操作 }}
要正确的确认识别引擎,关键是检查顺序要正确。
第一步:识别Opera;
必须检测 window.opera对象
if (window.opera){ engine.ver = window.opera.verson(); engine.opera = parseFloat(engine.ver);}
第二步:识别webkit;
WebKit的用户代理字符串中的“AppleWebkit”是独一无二的。
var ua = navigator.userAgent;if (window.opera){ engine.ver = window.opera.version(); engine.opera = parseFloat(engine.ver);}else if (/AppleWebKit\/(\S+)/.test(ua)){ engine.ver = RegExp["$1"]; engine.webkit = parseFloat(engine.ver);}
第三步:识别khtml;
KHTML中也包含Gecko,在排除KHTML之前无法准确检测Gecko的浏览器。
var ua = navigator.userAgent;if (window.opera){ engine.ver = window.opera.version(); engine.opera = parseFloat(engine.ver);}else if (/AppleWebKit\/(\S+)/.test(ua)){ engine.ver = RegExp["$1"]; engine.webkit = parseFloat(engine.ver);}else if (/KHTML\/(\S+)/.test(ua) || /Konqueror\/([^;]+)/.test(ua)){ engine.ver = RegExp["$1"]; engine.khtml = parseFloat(engine.ver);}
第四步:识别gecko ;
在排除webkit和khtml后就能确认gecko了
var ua = navigator.userAgent;if (window.opera){ engine.ver = window.opera.version(); engine.opera = parseFloat(engine.ver);}else if (/AppleWebKit\/(\S+)/.test(ua)){ engine.ver = RegExp["$1"]; engine.webkit = parseFloat(engine.ver);}else if (/KHTML\/(\S+)/.test(ua) || /Konqueror\/([^;]+)/.test(ua)){ engine.ver = RegExp["$1"]; engine.khtml = parseFloat(engine.ver);}else if (/rv:([^\)]+)\) Gecko\/\d{8}/.test(ua)){ engine.ver = RegExp["$1"]; engine.gecko = parseFloat(engine.ver);}
第五步:识别IE;
var ua = navigator.userAgent;if (window.opera){ engine.ver = window.opera.version(); engine.opera = parseFloat(engine.ver);}else if (/AppleWebKit\/(\S+)/.test(ua)){ engine.ver = RegExp["$1"]; engine.webkit = parseFloat(engine.ver);}else if (/KHTML\/(\S+)/.test(ua) || /Konqueror\/([^;]+)/.test(ua)){ engine.ver = RegExp["$1"]; engine.khtml = parseFloat(engine.ver);}else if (/rv:([^\)]+)\) Gecko\/\d{8}/.test(ua)){ engine.ver = RegExp["$1"]; engine.gecko = parseFloat(engine.ver);}else if (/MSIE ([^;]+)/.test(ua)){ engine.ver = RegExp["$1"]; engine.ie = parseFloat(engine.ver);}
var ua = navigator.userAgent;if (window.opera){ engine.ver = browser.ver = window.opera.version(); engine.opera = browser.opera = parseFloat(engine.ver);}else if (/AppleWebKit\/(\S+)/.test(ua)){ engine.ver = RegExp["$1"]; engine.webkit = parseFloat(engine.ver); //确定是Chrome还是Safari if (/Chrome\/(\S+)/.test(ua)){ browser.ver = RegExp["$1"]; browser.chrome = parseInt(browser.ver); }else if(/Version\/(\S+)/.test(ua)){ browser.ver = RegExp["$1"]; browser.safari = parseInt(browser.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; } browser.safari = browser.ver = safariVersion; }}else if (/KHTML\/(\S+)/.test(ua) || /Konqueror\/([^;]+)/.test(ua)){ engine.ver = browser.ver = RegExp["$1"]; engine.khtml = browser.konq = parseFloat(engine.ver);}else if (/rv:([^\)]+)\) Gecko\/\d{8}/.test(ua)){ engine.ver = RegExp["$1"]; engine.gecko = parseFloat(engine.ver); //确定不是firefox if(/Firefox\/(\S+)/.test(ua)){ browser.ver = RegExp["$1"]; browser.firefox = parseFloat(browser.ver); }}else if (/MSIE ([^;]+)/.test(ua)){ engine.ver = browser.ver = RegExp["$1"]; engine.ie = browser.ie = parseFloat(engine.ver);}
useragentstring.com列出了各种浏览器的版本以及用户代理字符串。
- 《JS高程(3)》客户端检测-第9章笔记(10)
- 《JS高程(3)》-第6章笔记(01)
- 《JS高程(3)》-第6章笔记(02)
- 《JS高程(3)》-第6章笔记(03)
- 《JS高程(3)》DOM节点层次Node类型-第10章笔记(11)
- 《JS高程(3)》DOM节点层次Document类型-第10章笔记(12)
- 《JS高程(3)》DOM节点层次Element类型-第10章笔记(13)
- 《JS高程(3)》DOM节点层次Text类型-第10章笔记(14)
- 《JS高程(3)》DOM节点层次Comment类型-第10章笔记(15)
- 《JS高程(3)》DOM节点层次CDATASection类型-第10章笔记(15)
- 《JS高程(3)》DOM节点层次DocumentType类型-第10章笔记(16)
- 《JS高程(3)》DOM操作技术-第10章笔记(17)
- JavaScript高程学习笔记之客户端检测(9)
- 《JS高程(3)》原型链继承模式 -第6章笔记(04)
- 《JS高程(3)》BOM-01(window&窗口)-第8章笔记(06)
- 《JS高程(3)》BOM-02(location)-第8章笔记(07)
- 《JS高程(3)》BOM-03(navigation)-第8章笔记(08)
- 《JS高程(3)》BOM-04(screen)-第8章笔记(09)
- 01.java实现冷饮批发管理系统-页面设计之【登录页面】
- python技巧(15)
- AVL树相关的一些操作
- uva 10935 卡片游戏
- ViewPager组合其他View的简单使用(一)
- 《JS高程(3)》客户端检测-第9章笔记(10)
- 二叉树的基本操作
- java注解概述
- Android中计算text文字大小的几个方法
- hibernate进阶之get和load方法的区别以及初识缓存
- 在spring项目中配置跨域访问
- 图个管理系统之实体类的设计
- maya2016中的python版本
- PHP设计模式之策略模式