浏览器测试Support(已移出jQuery,作用单独插件)
根据浏览器是否支持某项特定的功能特性,来决定程序的执行分支
由于$.browser基于navigator.userAgent检测浏览器类型,很容易被用户和浏览器欺骗,并且缺乏灵活性和不够全面。
因此最好避免编写基于特定浏览器的代码。
相对于$.browser,$.support针对浏览器特定特性的检测则更为有效。
$.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(空字符串、null、undefined、0等)时,默认为""
// match[2] || "0" :match[2]为false(空字符串、null、undefined、0等)时,默认为"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;
}
Support功能特性检测法
即根据浏览器是否支持某项特定的功能特性,来决定程序的执行分支,这种方法不考虑浏览器类型和版本,也不考虑浏览器升级带来的变化,更加安全、灵活,同时减少了维护工作,因此成为了当下主流的检测方法。例如绑定load事件的代码:
// 兼容事件模型,通过检测浏览器的功能特性,而非嗅探浏览器
if ( document.addEventListener ) {
// 使用较快的加载完毕事件
document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
// 注册window.onload回调函数
window.addEventListener( "load", jQuery.ready, false );
// 如果是IE事件模型
} else if ( document.attachEvent ) {
// 确保在onload之前触发onreadystatechange,可能慢一些但是对iframes更安全
document.attachEvent( "onreadystatechange", DOMContentLoaded );
// 注册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();
}
}
典型应用:盒模型
盒模型是CSS中的一个概念,CSS 将所有的网页元素都看做是一个矩形框,这个框由元素的内容(content)、内边距(padding)、边框(border)和外边距(margin)组成,
两种盒模型
IE传统模型:width和height属性包括内边距和边框宽度
W3C标准模型:width和height属性不包含边距和边框宽度
尺寸封装
jQueryn封装了这两种盒模型的差异,统一为W3C标准模型,并提供了修正后的接口:如下所示:
接口 计算公式
width, height content
innerWidth, innerHeight content+padding
outerWidth, outerHeight content+padding+border+可选的margin
Sizzle选择器
工作原理:
选择器表达式:'div>p',
块表达式 'div'、'p'
并列选择器表达式: 'div, p'
块分割器:对选择器表达式从左到右分割出一个个块表达式
查找器:对块表达式进行查找,找到的DOM元素数组叫候选集
过滤器:对块表达式和候选集进行过滤
关系过滤器: 对块表达式之间的关系进行过滤:+ 紧挨着的兄弟关系;> 父子关系;“ ”祖先关系;“~”之后的所有兄弟关系
候选集:查找器的结果,待过滤器进行过滤
映射集:候选集的副本,过滤器和关系过滤器对映射集进行过滤
工作流程:
1.使用块分割器对选择器表达式进行分割,从左向右
如果遇到","分割的并列选择器表达式,只分割到第一个逗号前的选择器表达式1,将剩余部分记录下来。
2.对最后一个块表达式进行查找Sizzle.find,结果放入到候选集set,并将块表达式中匹配的字符串部分删除
3.如果最后一个块表达式不为空(字符串),过滤器Sizzle.filter对set进行过滤
用分割器,对块表达式进行进行分割,查找,放到候选集set,删掉块表达式中已匹配的,剩余的部分记录下来
查找器进行查找匹配,
过滤器对set进行过滤
将以上查找和过滤得到候选集set复制,放入映射集checkSet,后边的过滤操作在checkSet上进行