欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

[原创] jQuery源码分析-06浏览器测试-Support

程序员文章站 2022-03-02 11:17:36
...

作者:nuysoft/高云 QQ:47214707 EMail:nuysoft@gmail.com

声明:本文为原创文章,如需转载,请注明来源并保留原文链接。 

 

读读写写,不对的地方请告诉我,多多交流共同进步,本章的的PDF下载在最后。

 

6. 浏览器测试 Support

浏览器之间的差异太让人头大了,本章也仅仅介绍jQuery实现浏览器兼容的基本思路,以及封装了种种差异后的接口。$.support中的众多属性和实现方式,超出了本文的写作初衷(一个头两个大啊),有兴趣的可以自行搜索、翻阅相关的资料。

兼容各种主流浏览器是JavaScript库的必修课之一,一般来说检测浏览器有两种方法:

l  检测navigator.userAgent,用户代理检测法

l  检测浏览器的功能特性,即功能特性检测法

6.1        用户代理检测法

window.navigatorNavigator对象,包含了正在使用的浏览器的信息:

属性

说明

appCodeName

代码名

appName

名称

appVersion

平台和版本信息

platform

操作系统和硬件平台

userAgent

用于HTTP请求的用户代理头

再看看navigatorIE和火狐下的测试:

l  IE8

属性

IE8

appCodeName

Mozilla

appName

Microsoft Internet Explorer

appVersion

4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0)

platform

Win32

userAgent

Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0)

l  Firefox

属性

Firefox

appCodeName

Mozilla

appName

Netscape

appVersion

5.0 (Windows)

platform

Win32

userAgent

Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0

 

测试结果让人纠结,既然。。。,ChromeSafariOpera就不测了!

不过,我们也发现userAgent似乎包含了较全的信息。浏览器在发起HTTP请求时,会把userAgent的信息作为请求头中User-Agent的值。服务器需要的话可以据此检测浏览器类型,对响应的内容进行适配,比如适配各种型号的手机浏览器。

jQuery就是根据userAgent属性来检测浏览器的类型,并提供了$.browser对象,通过$.browser,我们可以获取当前浏览器的类型和版本。

$.browser包含四种最流行的浏览器标记(IE,Mozilla,Webkit, Opera)和版本,对应的有效标记有:

l  webkit

l  safari(deprecated)

l  opera

l  msie

l  mozilla

$.browser不需等待$(document).ready就可以获取。使用示例:

$.browser.msie/mozilla/webkit/opera

$.browser.version

由于$.browser基于navigator.userAgent检测浏览器类型,很容易被用户和浏览器欺骗,并且缺乏灵活性和不够全面。因此最好避免编写基于特定浏览器的代码。相对于$.browser$.support针对浏览器特定特性的检测则更为有效。

API文档中可以看到,未来jQuery.browser可能会移到一个插件中

$.browser的实现代码如下:

// 用户代理检测正则表达式定义

var ...

rwebkit = /(webkit)[ \/]([\w.]+)/,

ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/,

rmsie = /(msie) ([\w.]+)/,

rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/,

// 到处都是把属性取出来,作为局部变量使用,可以减少跨作用域查询,提高性能

userAgent = navigator.userAgent,

// 用户代理匹配结果

browserMatch,

// 实际执行匹配的函数

uaMatch: function( ua ) {

    ua = ua.toLowerCase();

    // 依次匹配各浏览器

    var match = rwebkit.exec( ua ) ||

       ropera.exec( ua ) ||

       rmsie.exec( ua ) ||

       ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) ||

       [];

    // match[1] || "" match[1]false(空字符串、nullundefined0等)时,默认为""

    // match[2] || "0" match[2]false(空字符串、nullundefined0等)时,默认为"0"

    return { browser: match[1] || "", version: match[2] || "0" };},

// 将测试结果保存至jQuery.browser

browserMatch = jQuery.uaMatch( userAgent );

if ( browserMatch.browser ) {

    jQuery.browser[ browserMatch.browser ] = true;

    jQuery.browser.version = browserMatch.version;

}

// 不推荐使用safari标记,用webkit代替

if ( jQuery.browser.webkit ) {

    jQuery.browser.safari = true;

}

6.2        功能特性检测法

即根据浏览器是否支持某项特定的功能特性,来决定程序的执行分支,这种方法不考虑浏览器类型和版本,也不考虑浏览器升级带来的变化,更加安全、灵活,同时减少了维护工作,因此成为了当下主流的检测方法。例如绑定load事件的代码:

// 兼容事件模型,通过检测浏览器的功能特性,而非嗅探浏览器

if ( document.addEventListener ) {

    // Use the handy event callback

    // 使用较快的加载完毕事件

    document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );

 

    // A fallback to window.onload, that will always work

    // 注册window.onload回调函数

    window.addEventListener( "load", jQuery.ready, false );

 

// If IE event model is used

// 如果是IE事件模型

} else if ( document.attachEvent ) {

    // ensure firing before onload,

    // maybe late but safe also for iframes

    // 确保在onload之前触发onreadystatechange,可能慢一些但是对iframes更安全

    document.attachEvent( "onreadystatechange", DOMContentLoaded );

 

    // A fallback to window.onload, that will always work

    // 注册window.onload回调函数

    window.attachEvent( "onload", jQuery.ready );

 

    // If IE and not a frame

    // continually check to see if the document is ready

    var toplevel = false;

 

    try {

       toplevel = window.frameElement == null;

    } catch(e) {}

 

    if ( document.documentElement.doScroll && toplevel ) {

       doScrollCheck();

    }

}

6.3        盒模型

盒模型是CSS中的一个概念,CSS 将所有的网页元素都看做是一个矩形框,这个框由元素的内容(content)、内边距(padding)、边框(border)和外边距(margin)组成,如下图(摘自http://www.w3.org/TR/css3-box/):


[原创] jQuery源码分析-06浏览器测试-Support
            
    
    博客分类: jQuery javascriptjquery源码分析浏览器测试support

两种盒模型

l  IE传统模型:widthheight属性包括内边距和边框宽度

l  W3C标准模型:widthheight属性不包含边距和边框宽度

jQuery.boxModel

jQuery提供了boxModel属性,jQuery.boxModeltrue时,表示支持W3C盒模型,false表示支持IE传统盒模型。

尺寸封装

jQueryn封装了这两种盒模型的差异,统一为W3C标准模型,并提供了修正后的接口:

接口

计算公式

width, height

content

innerWidth, innerHeight

content+padding

outerWidth, outerHeight

content+padding+border+可选的margin

最后附个有趣的图,Chrome发布的时候看到的,会心一笑,不解释:


[原创] jQuery源码分析-06浏览器测试-Support
            
    
    博客分类: jQuery javascriptjquery源码分析浏览器测试support

  • [原创] jQuery源码分析-06浏览器测试-Support
            
    
    博客分类: jQuery javascriptjquery源码分析浏览器测试support
  • 大小: 9.5 KB
  • [原创] jQuery源码分析-06浏览器测试-Support
            
    
    博客分类: jQuery javascriptjquery源码分析浏览器测试support
  • 大小: 214.4 KB