浅谈JavaScript中的能力检测
引言
我们知道,各个版本的浏览器有着许多不一致性。理想状态下,应该是所有的浏览器都提供一套标准的API接口。但是现实中,各个版本的浏览器存在的怪癖非常多,我们通常都是使用客户端检测来作为补救措施。但是我们应该知道,不到万不得已,不要使用客户端检测。只要能找到更通用的方法,就应该优先采用更通用的方法。总之。先设计最通用的方案,在使用特定于浏览器的技术增强该方案。
1、能力检测
最常用的也是最广泛使用的客户端检测技术是能力检测(特性检测)。能力检测的目标不是识别特定的浏览器,而是识别浏览器的能力。使用这种方式无需顾及浏览器如何如何,只需确定浏览器是否支持特定的能力,就可以给出相关的方案。其基本默认如下:
//特性检测
if (object.propertyInQuestion) {
//使用object.propertyInQuestion
}
举例来说,IE5不支持document.getElementById这个DOM方法。尽管可以使用非标准的document.all属性实现相同的功能。但是早期的IE的确不支持document.getElementById。所以通过下面的特性检测来保证浏览器的兼容性。请看下面的例子:
function getElement(id) {
if (document.getElementById) {
return document.getElementById(id);
}
else if (document.all) {
return document.all[id];
}
else {
throw new Error("浏览器版本太老了,不存在搜索DOM接口");
}
}
我们看到方法是想返回指定Id的DOM元素。document.getElementById()是实现这一功能的标准方式,所以首先检测它。如果浏览器不支持这个方法,那么久退而求其次使用document.all属性来实现类似的功能。如果这两个特性都无法使用,那么说明这个方法无法使用了。
第二个重要的概念在于:必须检测实际要用到的特性。一个特性存在,并不意味着另一个特性也存在。请看下面的例子:
function getWindowWidth() {
//假设是IE浏览器
if (document.all) {
//错误的用法
return document.documentElement.clientWidth;
}
else {
return window.innerWidth;
}
}
这是一个错误使用能力检测的例子。在这个例子中,首先检测document.all这个特性。然后使用document.documentElement.clientWidth返回窗体的宽度。IE8之前的浏览器确实不支持window.innerWidth属性。但是document.all属性成立的浏览器并不是只有IE。Opera也支持这个属性,也支持window.innerWidth。我们使用到了document.documentElement.clientWidth,这个也是需要进行特性检测的。
2、更可靠的能力检测
能力检测对于想知道某个特性是否会按适当的方式行事非常有效。我们在上面介绍的利用类型转换来确定某个对象成员是否存在,但这样是还是不知道该成员是不是你想要的。下面我们来看一个例子:
//不要这样做,这只是检测了是否存在相应的方法--这不是能力检测
function isSortable(object) {
return !!object.sort;
}
这个函数通过检测对象是否有sort方法来确定对象是否支持排序。但是如果一个对象包含了sort属性,那么也会返回true。这会导致一些问题。所以更好的方法是检测sort是否是一个函数。例如:
function isSortable(object) {
return typeof object.sort === "function";
}
这里的typeof操作符用于确定sort的确是一个函数。所以后期可以使用sort进行排序。
在可能的情况下,应该尽量使用typeof操作符进行能力检测。
浅谈JavaScript中的能力检测的更多相关文章
- 浅谈JavaScript中的闭包
浅谈JavaScript中的闭包 在JavaScript中,闭包是指这样一个函数:它有权访问另一个函数作用域中的变量. 创建一个闭包的常用的方式:在一个函数内部创建另一个函数. 比如: functio ...
- 浅谈JavaScript中的null和undefined
浅谈JavaScript中的null和undefined null null是JavaScript中的关键字,表示一个特殊值,常用来描述"空值". 对null进行typeof类型运 ...
- 浅谈JavaScript中的正则表达式(适用初学者观看)
浅谈JavaScript中的正则表达式 1.什么是正则表达式(RegExp)? 官方定义: 正则表达式是一种特殊的字符串模式,用于匹配一组字符串,就好比用模具做产品,而正则就是这个模具,定义一种规则去 ...
- 浅谈JavaScript中的内存管理
一门语言的内存存储方式是我们学习他必须要了解的,接下来让我浅谈一下自己对他的认识. 首先说,JavaScript中的变量包含两种两种类型: 1)值类型或基本类型:undefined.null.numb ...
- 浅谈JavaScript中的事件
引言 Html页面与JavaScript之间的交互是通过事件来完成的.事件,就是文档或者浏览器窗口中发生的一些特定的交互瞬间.可以使用侦听器(处理程序)来预订事件,以便事件发生时执行相应的代码.这在传 ...
- 浅谈JavaScript中闭包
引言 闭包可以说是JavaScript中最有特色的一个地方,很好的理解闭包是更深层次的学习JavaScript的基础.这篇文章我们就来简单的谈下JavaScript下的闭包. 闭包是什么? 闭包是什么 ...
- 浅谈JavaScript中的继承
引言 在JavaScript中,实现继承的主要方式是通过原型链技术.这一篇文章我们就通过介绍JavaScript中实现继承的几种方式来慢慢领会JavaScript中继承实现的点点滴滴. 原型链介绍 原 ...
- 浅谈JavaScript中的原型模式
在JavaScript中创建对象由很多种方式,如工厂模式.构造函数模式.原型模式等: <pre name="code" class="html">/ ...
- 浅谈JavaScript中继承的实现
谈到js中的面向对象编程,都有一个共同点,选择原型属性还是构造函数,两者各有利弊,而就片面的从js的对象创建以及继承的实现两个方面来说,官方所推荐的是两个相结合,各尽其责,各取其长,在前面的例子中,我 ...
随机推荐
- C#中的集合有几种?
C#中的集合有几种? Array ArrayList List<T> Stack<T> Queue<T> Dictionary<K,V> HashTab ...
- 兼容性问题
直接在html文档中使用 来表示空格,在不同浏览器中的占位大小是不一样的. 因为不同浏览器默认的字体是不一样的,不同字体下的空格表示 占位大小不一致. 我们对 指定使用同样的字体就能让 显示同样的占位 ...
- AFnetworking3.1的基本使用
听说之后AFHttpWorking版本可能会影响到苹果的审核,今天下了最新版本的AFHttpWorking,并且做了简单的封装,我这里是通过cocoapods下载了两个工具 1=AFHttpWorki ...
- 简进祥===AFNetWorking 下载视频文件
获取沙盒中的Documents地址的代码. NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUs ...
- 最新版CocoaPods的使用与安装-以导入ReactiveCocoa框架为例
一.什么是CocoaPods?前言: 思考如何引入一个第三方框架. 例如: 百度地图SDK.友盟.ShareSDK. 信鸽推送等.从github或某处下载第三方SDK工程中导入所需要的SDK的文件 . ...
- 【Codeforces-707D】Persistent Bookcase DFS + 线段树
D. Persistent Bookcase Recently in school Alina has learned what are the persistent data structures: ...
- JSP隐含变量和Spring中Model在EL表达式中的读取顺序
偶然中存在着必然,必然中存在着偶然 偶然出现的bug,必然存是由代码的不合理甚至错误的 代码逻辑越长,越复杂,就越容易出现bug 之前项目里几次偶然出现了一个bug,简单的描述就是第一次新增了之后进行 ...
- [NOIP2014] 提高组 洛谷P1328 生活大爆炸版石头剪刀布
题目描述 石头剪刀布是常见的猜拳游戏:石头胜剪刀,剪刀胜布,布胜石头.如果两个人出拳一样,则不分胜负.在<生活大爆炸>第二季第8 集中出现了一种石头剪刀布的升级版游戏. 升级版游戏在传统的 ...
- (转载)LCA问题的Tarjan算法
转载自:Click Here LCA问题(Lowest Common Ancestors,最近公共祖先问题),是指给定一棵有根树T,给出若干个查询LCA(u, v)(通常查询数量较大),每次求树T中两 ...
- django 模板中url的处理
在模板中直接添加‘/home’这样的链接是十分不推荐的,因为这是一个相对的链接,在不同网页中打开可能会返回不一样的结果. 所以推荐的是 <a href="{{ object.get_a ...