判断JavaScript对象是否可用的最正确方法分析


Posted in Javascript onOctober 03, 2008

原文:http://www.quirksmode.org/js/support.html
原文作者:Peter-Paul Koch

以下为对原文的翻译:

判断对象存在的方法

很快你就会注意到,JavaScript的部分功能在部分浏览器中无效。如果你要使用一些脚本的高级特性,你首先要检查浏览器是否支持要使用的对象,本文具体说明判断的正确方法。

通过判断浏览器的版本:不!

如果你想知道浏览器是否支持代码中使用的那些对象,记住,永远都不要通过浏览器的版本来判断。我确定你知道,有些浏览器支持你的代码,而有些浏览器不支持你的代码,可是你考虑过其他的浏览器么?那些不知名的小浏览器?

就算你可以检测出90%的用户所使用的浏览器及版本,还是有一些不出名的浏览器不能正确运行你的代码,结果要么是一大堆异常信息,要么是某些脚本没有被正确的执行。不管是哪种情况,你都是在使用漏洞百出的代码欺骗最终浏览网站的用户。

个案研究:mouseovers

一个古老的个案可以证实上述的说法。虽然这种情况现在已经不存在,但是同样原理的例子还是存在的。

一个公认的事实就是IE 3不支持document.images这个数组,但这个数组对mouseover脚本又是极为重要。所以我们就应该禁止mouseover脚本在IE 3浏览器中执行。解决方案之一就是对浏览器进行判断,当判断出用户使用的浏览器是IE 3的时候,就不执行这个函数。

但是,在大多数操作系统中,Netscape 2浏览器同样不支持document.images数组。如果你仅仅判断浏览器是不是IE 3,那么使用Netscape 2的用户就会看到一大堆异常信息。

那为什么不连同Netscape 2一起检测呢?因为就算这样做也是无事于补。

运行在OS/2上的Netscape 2是和Netscape 3完全兼容的,而且可以很好的处理mouseover效果。尽管如此,大家为什么还会经常看不到这个效果呢?因为web开发者使用了浏览器检测的手段,在 mouseover脚本中屏蔽了Netscape 2浏览器。因此开发者们,在没有充足理由的情况下,剥夺了用户拥有良好互动体验的权利。合适的对象检测方法可以避免这种情况的发生。

最后,越来越多的浏览器允许用户把浏览器的认证字符串修改为自己喜欢的内容,这样就存在很大的可能性,检测不出用户真实使用的浏览器以及版本,自然就不能保证无故障的运行代码了。由此,web开发者再次剥夺了用户额外互动效果的权利。更糟的是,这样的代码通常写的很烂。

既然浏览器的版本不可靠,那么是否JavaScript的版本更加可信一些呢?

通过判断JavaScript的版本:不!

在最初规划的时候,Netscape完全意识到未来的浏览器会支持比现在多得多的对象,而web开发者必须能够把新老浏览器区分开来。

起初的计划是让开发者对浏览器的版本进行判断。比如某某浏览器只能支持JavaScript 1.x等。在script标签中增加version属性,这样如果浏览器不支持相应版本的JavaScript,自然就不会执行这段脚本。

但是,当Microsoft涉足浏览器市场后,这个想法就无法进行下去了。尽管早在Netscape 4和IE 4的时候就都支持JavaScript 1.2,可是就算再有想象力的人也不会相信他们支持的是相同的JavaScript 1.2。因为这个版本号已经过时了,而且肯定和对象检测不相干。

所以不要使用JavaScript的版本号来做什么,他们没什么实际的作用。

正确的方法:对象判断

相反,我们只需通过简单的方法来判断浏览器是否支持要使用的对象(或者是方法、数组或者属性)。我们还是使用mouseover这个例子。这段脚本依赖于document.images这个数组,所以最重要的事情当然是判断浏览器是否支持他,下面是具体的做法:

if (document.images)
{
do something with the images array
}

现在你有了一个完全的保障,运行这段代码的浏览器肯定支持这段脚本。条件语句判断document.image这个数组是否存在,如果返回true,那么这段脚本将会被执行,反之如果这个数组不存在,将会返回false,而且这段脚本肯定不会被执行。

还有一个常用的检测是针对window.focus的。这是一个方法(一条你告诉JavaScript要去做什么的命令)。如果我们要使用这个方法,我们必须首先检测浏览器是否支持这个方法。

检测函数是否存在的正确方法如下,牢记千万不要在函数后面加括号:

if (window.focus)

上面这段代码的含义是:“浏览器是否支持window.focus这个函数”,而下面这段代码的含义不同:

if (window.focus())

这段代码是对focus的结果进行判断,而且已经假设浏览器是支持focus方法的,而如果不支持,这时候就会报异常了。加了括号以后实际上执行了函数,而这并不是我们想要的状况。所以检测的时候不要加括号,而只有在检测通过后才加上括号执行这个函数。比如下面这个例子:

if (window.focus) window.focus()

重点

以上讨论的所有重点就是:在JavaScript中,如果你要使用document.images,首先判断是否支持document.images。如果你要使用window.focus方法,首先判断是否浏览器是否支持这个方法。

如果你总是在使用对象前进行检测,你的脚本将不会产生类似问题的异常,付出的代码只是有些功能在部分浏览器中被屏蔽掉了而已。

译者注:

任何战争都是会带来很多副作用的,本文所介绍的情况主要是发生在浏览器大战的时候的,就像冷战一样,造成了很多遗留的问题。但是后来ecma- 262标准的实施,让这种情况得到些许缓和,可是在ecma-262第三版中明确规定,允许各家自己对其进行扩展,扩展的结果自然就是不兼容,自然要使用 本文的方法进行判断。索性,我们现在只是不用判断所有的对象,如果一个浏览器宣布支持ecma-262标准,至少我们知道哪些对象不用判断,也算是一种慰 藉吧。

Javascript 相关文章推荐
Javascript学习笔记9 prototype封装继承
Jan 11 Javascript
加载jQuery后$冲突的解决办法
Jul 09 Javascript
JS拖动技术 关于setCapture使用
Dec 09 Javascript
javascript数组去掉重复
May 12 Javascript
js中符号转意问题示例探讨
Aug 19 Javascript
javascript删除字符串最后一个字符
Jan 14 Javascript
Javascript基础_嵌入图像的简单实现
Jun 14 Javascript
基于JS代码实现图片在页面中旋转效果
Jun 16 Javascript
jQuery实现的跨容器无缝拖动效果代码
Jun 21 Javascript
js 定义对象数组(结合)多维数组方法
Jul 27 Javascript
Angularjs使用directive自定义指令实现attribute继承的方法详解
Aug 05 Javascript
何时使用Map来代替普通的JS对象
Apr 29 Javascript
IE与firefox之jquery用法区别
Oct 03 #Javascript
jquery的颜色选择插件实例代码
Oct 02 #Javascript
初学JavaScript_03(ExtJs Grid的简单使用)
Oct 02 #Javascript
JavaScript下申明对象的几种方法小结
Oct 02 #Javascript
初学JavaScript第二章
Sep 30 #Javascript
select组合框option的捕捉实例代码
Sep 30 #Javascript
javascript优先加载笔记代码
Sep 30 #Javascript
You might like
第九节--绑定
2006/11/16 PHP
php IP转换整形(ip2long)的详解
2013/06/06 PHP
深入apache配置文件httpd.conf的部分参数说明
2013/06/28 PHP
php删除一个路径下的所有文件夹和文件的方法
2018/02/07 PHP
PHP5.5基于mysqli连接MySQL数据库和读取数据操作实例详解
2019/02/16 PHP
jquery中dom操作和事件的实例学习 仿yahoo邮箱登录框的提示效果
2011/11/30 Javascript
JS弹出窗口代码大全(详细整理)
2012/12/21 Javascript
判断及设置浏览器全屏模式
2014/04/20 Javascript
JavaScript实现带箭头标识的多级下拉菜单效果
2015/08/27 Javascript
JS获取元素多层嵌套思路详解
2016/05/16 Javascript
AngularJS ng-blur 指令详解及简单实例
2016/07/30 Javascript
canvas压缩图片转换成base64格式输出文件流
2017/03/09 Javascript
基于Vue的SPA动态修改页面title的方法(推荐)
2018/01/02 Javascript
Vuex 入门教程
2018/01/10 Javascript
完美解决axios跨域请求出错的问题
2018/02/05 Javascript
使用Vue-cli 3.0搭建Vue项目的方法
2018/06/07 Javascript
vue2.0$nextTick监听数据渲染完成之后的回调函数方法
2018/09/11 Javascript
[00:33]2016完美“圣”典风云人物:Sccc宣传片
2016/12/03 DOTA
详解Python中的循环语句的用法
2015/04/09 Python
python学生管理系统学习笔记
2019/03/19 Python
简单了解python的break、continue、pass
2019/07/08 Python
浅析Python 引号、注释、字符串
2019/07/25 Python
django的csrf实现过程详解
2019/07/26 Python
python实现通过flask和前端进行数据收发
2019/08/22 Python
Pytorch 数据加载与数据预处理方式
2019/12/31 Python
pytorch 计算ConvTranspose1d输出特征大小方式
2020/06/23 Python
会计专业自我鉴定范文
2013/10/06 职场文书
应付会计岗位职责
2013/12/12 职场文书
《石榴》教学反思
2014/03/02 职场文书
国庆宣传标语
2014/06/30 职场文书
党员个人对照检查材料思想汇报
2014/09/16 职场文书
教师个人事迹材料
2014/12/17 职场文书
2015年图书馆个人工作总结
2015/05/26 职场文书
2016年公共机构节能宣传周活动总结
2016/04/05 职场文书
Django 如何实现文件上传下载
2021/04/08 Python
java高级用法JNA强大的Memory和Pointer
2022/04/19 Java/Android