欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

jQuery 源碼分析筆記(5) jQuery.support

 更新時(shí)間:2011年06月19日 23:54:26   作者:  
接下來(lái)是非常糾結(jié)的一個(gè)話題,也是所有JS庫(kù)必須實(shí)現(xiàn)的一個(gè)功能:瀏覽器兼容性和為開(kāi)發(fā)者屏蔽這些差異。
其中jQuery.browser已經(jīng)提供了根據(jù)UserAgent檢測(cè)的瀏覽器信息。而jQuery.support 使用特性檢測(cè)來(lái)檢查瀏覽器的功能以及Bug。

和文檔一樣,首先說(shuō)明一下,這個(gè)模塊是很底層的代碼,基本不需要在日常開(kāi)發(fā)中使用,但是插件的開(kāi)發(fā)者更需要。因?yàn)椴寮枰嫒莞鱾€(gè)瀏覽器。首先看一下 support模塊提供了哪些瀏覽器特性的檢測(cè),以下結(jié)果是在Chrome 13 Dev下看到的結(jié)果。根據(jù)瀏覽器的不同,這里的成員可能會(huì)有變化。(PS:再次吐槽IE,大部分屬性都是IE比較特別)

  • ajax: true。是否支持XMLHttpRequest對(duì)象。老版本的IE不支持,必須用ActiveX。 * appendChecked: true。 * boxModel: true。是否根據(jù)W3C CSS盒模式渲染。IE6和7的Quirks模式為False。 * changeBubbles: true。change事件是否沿著DOM樹(shù)冒泡。這是W3C DOM事件模型的要求,但是IE目前為止是False。jQuery模擬了這個(gè)冒泡特性。 * checkClone: undefined。在克隆Radio Button或者CheckBox時(shí)是否保留選中狀態(tài)。以前說(shuō)createFragment緩存的時(shí)候提到過(guò),WebKit內(nèi)核是不保留的。 * checkOn: false。CheckBox在沒(méi)有指定時(shí)是否默認(rèn)為On。 * cors: true。XMLHttpRequest對(duì)象是否帶有withCredentials屬性??梢詧?zhí)行跨域請(qǐng)求。或者沒(méi)有這個(gè)屬性,但是有其他途徑可以實(shí)現(xiàn)跨域XHR請(qǐng)求的,也是True(比如通過(guò)Windows Gadget)。 * cssFloat: true。支持cssFloat的CSS屬性。IE是False,它使用了styleFloat。 * deleteExpando: true。 * focusinBubbles: false。 * getSetAttribute: true。 * hrefNormalized: true。對(duì)一個(gè)a元素調(diào)用getAttribute("href")時(shí),是否返回原始指定的URL。IE會(huì)返回完整路徑。比如對(duì)于href="1.html"的鏈接,IE會(huì)得到http://..../1.html。 * htmlSerialize: true。是否可以用innerHTML插入link元素。IE為false。 * inlineBlockNeedsLayout: false。為了讓block元素表現(xiàn)inline-block,是否需要為inline并且hasLayout(IE下的概念,大部分布局問(wèn)題的根源)。IE8以下有問(wèn)題。 * leadingWhitespace: true。innerHTML屬性是否嚴(yán)格按照代碼渲染。IE6-8中會(huì)去掉前置的空白。(所以使用Markdown寫(xiě)的這篇文章在IE下有格式問(wèn)題,因?yàn)閾Q行不見(jiàn)了) * noCloneChecked: true。1.5.1新屬性。檢測(cè)瀏覽器是否克隆checked擴(kuò)展屬性。IE為false。 * noCloneEvent: true。拷貝的元素是否會(huì)帶有事件處理函數(shù)(即Event handler是否被拷貝過(guò)去)。IE為false。 * opacity: true。是否支持opacity CSS屬性(透明度)。IE為false,它使用alpha filter。 * optDisabled: true。已經(jīng)disabled的select元素中的option元素是否默認(rèn)為disabled。 * optSelected: true。一個(gè)默認(rèn)被選中的option元素的selected屬性是否正常。 * radioValue: true。 * reliableHiddenOffsets: true。在table的cells被設(shè)置為display:none的時(shí)候,仍然有offsetWidth/Height。即hidden靠不住。只有IE8有這個(gè)問(wèn)題。參見(jiàn)4512號(hào)bug * reliableMarginRight: true。div有顯式的寬度,但是沒(méi)有margin-right。此時(shí)基于容器計(jì)算margin-right不正確。舊版本W(wǎng)ebKit有問(wèn)題。參見(jiàn)3333號(hào)bug * scriptEval(): 1.5.1版本前,這是一個(gè)屬性,而現(xiàn)在變成函數(shù)了。檢測(cè)一個(gè)inline的腳本在使用標(biāo)準(zhǔn)的DOM操作函數(shù)被添加時(shí)是否會(huì)自動(dòng)執(zhí)行。比如appendChild和createTextNode。IE是false,它使用text來(lái)插入腳本。 * shrinkWrapBlocks: false。元素在hasLayout的情況下是否會(huì)撐大父節(jié)點(diǎn)。只有IE6是true。 * style: true。一個(gè)元素的inline的style屬性是否可以用DOM屬性訪問(wèn)。比如getAttribute("style")。IE是false,它使用cssText屬性。 * submitBubbles: true。submit事件是否沿著DOM樹(shù)冒泡。IE為false,jQuery模擬了這個(gè)冒泡過(guò)程。 * tbody: true。一個(gè)空的table元素是否可以沒(méi)有tbody元素。根據(jù)HTML規(guī)范,子元素是可選的。但是IE是false,所以會(huì)自動(dòng)插入一個(gè)tbody元素。

jQuery創(chuàng)建了幾個(gè)元素用來(lái)判斷瀏覽器特性。如下:

復(fù)制代碼 代碼如下:

var div = document.createElement("div");
div.setAttribute("className", "t");
div.innerHTML = " <LINK><TABLE><TBODY></TBODY></TABLE><A style="FLOAT: left; TOP: 1px; opacity: .55" href="http://www.dbjr.com.cn/a">a</A><INPUT type=checkbox>";
all = div.getElementsByTagName("*");
a = div.getElementsByTagName("a")[0];
var select = document.createElement("select");
opt = select.appendChild(document.createElement("option"));
input = div.getElementsByTagName("input")[0];

其中div元素相當(dāng)有內(nèi)涵。包括了空白開(kāi)頭,空Table元素,inline style,opacity等等。除了一行行看代碼和注釋也沒(méi)啥其他筆記了:
復(fù)制代碼 代碼如下:

support = {
// IE會(huì)把開(kāi)頭的空格去掉,所以nodeType不是3(文本)
leadingWhitespace: (div.firstChild.nodeType === 3),
// IE會(huì)自動(dòng)插入tbody,所以length不同
tbody: !div.getElementsByName("tbody").length,
// IE不允許用這種方式插入link元素
htmlSerialize: !!div.getElementsByTagName("link").length,
// 如果正常獲得style的話,這個(gè)正則表達(dá)式應(yīng)該會(huì)正常通過(guò)
style: /top/.test(a.getAttribute("style")),
// href屬性應(yīng)該是原始指定的字符串,IE會(huì)修改為http開(kāi)頭的絕對(duì)URL
hrefNormalized: (a.getAttribute("href") === "/a"),
// 能得到opacity屬性。這里使用了正則表達(dá)式,是為了繞過(guò)WebKit[5145號(hào)bug](http://dev.jquery.com/ticket/5145)
// 但是這應(yīng)該是一個(gè)早期版本的問(wèn)題。起碼在Chrome 13中,不用正則也是對(duì)的。
opacity: /^0.55$/.test(a.style.opacity),
// IE使用styleFloat
cssFloat: !!a.style.cssFloat,
// div中的checkbox沒(méi)有指定值,看默認(rèn)值是否是on。WebKit是""。所以我的結(jié)果是false
checkOn: (input.value === "on"),
// 這個(gè)select只有一個(gè)option元素,所以渲染時(shí),這個(gè)option是默認(rèn)選中的。此時(shí)selected應(yīng)該是true。
optSelected: opt.selected,
submitBubbles: true,
changeBubbles: true,
focusinBubbles: false,
deleteExpando: true,
noCloneEvent: true,
inlineBlockNeedsLayout: false,
shrinkWrapBlocks: false,
reliableMarginRight: true
};

下面的大部分都是按部就班的測(cè)試。其中BoxModel的測(cè)試比較有趣:
復(fù)制代碼 代碼如下:

div.innerHTML = ""; // 從頭來(lái)
div.style.width = div.style.paddingLeft = "1px";
body = document.createElement("body");
body.style.width = 0;
body.style.height = 0;
body.style.border = 0;
body.style.margin = 0; // 全部設(shè)置為0
body.appendChild(div);
document.documentElement.insertBefore(body, document.documentElement.firstChild);
support.boxModel = div.offsetWidth === 2;
// 這個(gè)時(shí)候div嵌套在body下。而body長(zhǎng)寬高,邊框和margin都是0。所以div的偏移應(yīng)該就是它自己的paddingLeft+width。如果不對(duì),就說(shuō)明盒模式不對(duì)。

然后值得注意的是事件的冒泡,注釋中提到的技術(shù)參考文章鏈接已經(jīng)失效。請(qǐng)自己搜索"Detecting event support without browser sniffing"
復(fù)制代碼 代碼如下:

// attachEvent是IE的,所以這里實(shí)際上只檢查了IE,其他瀏覽器都是前面設(shè)置的默認(rèn)值。
if(div.attachEvent) {
for(i = {
submit: 1,
change: 1
focusin: 1
}) {
eventName = "on" + i;
isSupported = (eventName in div);
if(!isSupported) {
div.setAttribute(eventName, "return;");
isSupported = (typeof div[eventName] === "function");
}
support[i + "Bubbles"] = isSupported;
}
}

PS: 瀏覽器檢測(cè)是一個(gè)很糾結(jié),很細(xì)節(jié)的任務(wù)。這個(gè)筆記慢慢完善中……

18:30補(bǔ)充:經(jīng)過(guò)IE9的測(cè)試,以上大部分IE相關(guān)問(wèn)題都已經(jīng)不存在。以下是IE9+Win7的測(cè)試結(jié)果:
復(fù)制代碼 代碼如下:

$.support
{
boxModel: true,
changeBubbles: true,
checkClone: true,
checkOn: true,
cssFloat: true,
deleteExpando: true,
hrefNormalized: true,
htmlSerialize: true,
leadingWhitespace: true,
noCloneEvent: false,
opacity: true,
optSelected: false,
parentNode: true,
scriptEval: true,
style: true,
submitBubbles: true,
tbody: true
}

相關(guān)文章

最新評(píng)論