跨浏览器兼容问题

一、浏览器兼容问题的常用解决方案

对于浏览器的不一致问题,有两大类解决方法,第一类是采用迁就各方的"最小公分母"策略,也即选用所有浏览器都支持的方式来解决问题;第二类是采用客户端检测方案,客户端检测又分三种,按照使用频率依次是能力检测、怪癖检测和用户代理检测。

1、能力检测:不能识别浏览器,其目的是用于识别浏览器是否支持某一属性或方法。能力检测在使用时遵循两个规则:一个是先检测较常用的特性(可以减少条件判断的次数);另一个是要用哪个特性就检测哪个特性,而不是通过检测一个特性来推断另一个特性是否存在。

能力检测的注意事项:

(1)能力检测时为了取得更可靠的效果,不仅仅要检测某个属性是否存在,还要检测其是否会以适当的行为进行,所以在检测时最好用typeof操作符(使用typeof的还有一个原因是IE中会存在一些怪癖,如xhr.open如果不使用typeof进行判断会报错),比如想检测对象是否支持sort方法,如果只检测属性是否存在,那么如果对象中存在同名的sort属性(不是方法),判断条件也成立,但在IE中使用typeof操作符也可能存在一些小问题,因为IE早期版本中把宿主对象实现为COM对象,这种情况对于同一个函数(如document.createElement())使用typeof操作符可能会返回function也可能返回object(IE)。

(2)如果知道自己的应用需要使用某些特定的(并不是为所有浏览器支持的)浏览器特性,则最好一次性把所有浏览器都检测了,一方面方便阅读代码(可以一下看出自己的代码需要使用哪些特性),另一方面后续也不用再重新检测节省时间。

(3)在检测时,条件语句中尽量使用双逻辑非操作符(使用双逻辑非操作符可以直接得到布尔值,而如果直接使用值本身则需要把类型转换的布尔值先存起来再调用if语句,所以使用双逻辑非操作符效率更高。)

2、怪癖检测:不能识别特定的浏览器。怪癖检测用于了解浏览器存在什么bug,通常需要运行一小段代码来确定某一特性在浏览器中不能正常工作,比如safari 3以前的版本会枚举被隐藏的属性(比如toString()方法的[[Enumerable]]特性是false,但在for-in循环中会被列出来。)

怪癖检测注意事项:

(1)只需要检测对自己的应用程序会有直接影响的怪癖,不用检测所有怪癖,否则会影响性能。

(2)应该在脚本一开始就执行怪癖检测,以便尽早解决问题。

3、用户代理检测:能够知道浏览器名称、浏览器版本号、操作系统等详细信息。通过navigator.userAgent获取到用户代理字符串,并对该字符串中的某一部分进行正则测试即可获得有用信息。

用户代理检测注意事项:

(1)由于存在电子欺骗(一些浏览器为了让自己不要被一些服务站点拒之门外,在自己的用户代理字符串中加入一些伪装信息以迷惑服务器的行为称为电子欺骗),所以此类检测比较复杂。

(2)检测的顺序:Opera(可以完全伪装成别的浏览器而不留下一点自己的信息,所以需要最先检测)--Webkit(含有KHTML和Gecko两个字符串,所以需要提前区分开避免与这两者混淆)--KHTML/Konqueror(含有Gecko字符串)--Gecko--IE

(3)使用用户代理检测的情况:使用能力检测或怪癖检测解决不了问题;同一款浏览器在不同平台下具备不同的能力;为了跟踪分析等目的需要知道确切的浏览器。

4、DOM一致性检测,与能力检测目的类似,但不完全是能力检测。

DOM分为多个级别也包含多个部分,所以有时需要检测浏览器实现了DOM的哪些部分,使用DOM1级提供的document.implementation.hasFeature(DOM功能,版本号)方法即可实现,不过该方法的结果很容易被伪造,而且浏览器可能支持某项功能,但它并没有完全按照DOM规范对其实现,所以该方法最好结合能力检测同时使用。

二、跨浏览器兼容的一些实例

1、对于在特定浏览器中没有的方法,在使用时,为了防止报错,可以将方法放在try....catch...语句块中,在try语句中使用常规方法,在catch语句中针对不支持的浏览器作特殊处理。(怪癖检测的一种方式)。

例子:

// 将一个NodeList对象转换为数组

function convertToArray(nodes){

    var array = null;

    try {

        array =Array.prototype.slice.call(nodes,0)    //非IE浏览器能够正常运行

    }catch(ex) {

        array = new Array();

        for(var i= 0, len = nodes.length; i

            array.push(nodes[i]);

            }

    }

    return array;

}


2、对于不同浏览器支持程度不一致的属性或方法应尽量少用,尽量用其他通用方法替代。比如document.doctype和html元素外部的注释在不同浏览器中对其处理方式有挺大差别,所以这些属性在实际中用处不大。(最小公分母策略


你可能感兴趣的:(跨浏览器兼容问题)