3、構(gòu)建Jquery的Dom元素
在jQuery.fn.init函數(shù)中,最終的結(jié)果是把Dom元素放到j(luò)Query對(duì)象的集合,我們可以傳入單個(gè)Dom元素或Dom元素集合直接把其存到j(luò)Query對(duì)象的集合。但是如果第一個(gè)參數(shù)是string類型的話,如#id就要把Dom文檔樹去查找。對(duì)于html的片斷就得生成Dom元素。我們?cè)龠M(jìn)一步,傳入的單個(gè)Dom元素或Dom元素集合參數(shù)又是從那里來的?我們可以通過Dom元素的直接或間接的查找元素的方式。
這一部分首先分析如何從html的片斷就得生成Dom元素,然后分析jQuery是如何通過直接或間接的方式在在Dom樹中找到dom元素,第三就是分析基于CSS1~CSS3的CSS selector。
3.1生成Dom元素
Init方法中通過jQuery.clean([match[1]], context);來實(shí)現(xiàn)把html片斷轉(zhuǎn)換成Dom元素,這是一個(gè)靜態(tài)方法:
// 把html轉(zhuǎn)換成Dom元素,elems多個(gè)html string 的數(shù)組
clean : function(elems, context) {
var ret = [];
context = context || document;//默認(rèn)的上下文是document
//在IE中!context.createElement行不通,因?yàn)樗祷貙?duì)象類型
if (typeof context.createElement == 'undefined')
//這里支持context為jQuery對(duì)象,取第一個(gè)元素。
context = context.ownerDocument || context[0]
&& context[0].ownerDocument || document;
jQuery.each(elems, function(i, elem) {
// 把int 轉(zhuǎn)換成string的最高效的方法
if (typeof elem == 'number')elem += '';
if (!elem) return;// 為'',undefined,false等時(shí)返回
if (typeof elem == "string") {// 轉(zhuǎn)換html為Dom元素
// 修正 "XHTML"-style 標(biāo)簽,對(duì)于如<div/>的形式修改為<div></div>
//但是對(duì)于(abbr|br|col|img|input|link|meta|param|hr|area|embed)
//不修改 。front=(<(\w+)[^>]*?)
elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all,front, tag) { returntag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?all: front + "></" + tag+ ">";} );
// 去空格,否則indexof可能會(huì)出不能正常工作
var tags = jQuery.trim(elem).toLowerCase(),
div = context.createElement("div");//在上下文中創(chuàng)建了一個(gè)元素<div>
// 有些標(biāo)簽必須是有一些約束的,比如<option>必須在<select></select>中間
// 下面的代碼在大部分是對(duì)<table>中子元素進(jìn)行修正。數(shù)組中第一個(gè)元素為深度 var wrap =
//<opt在開始的位置上(index=0)就返回&&后面的數(shù)組,這是對(duì)<option>的約束
!tags.indexOf("<opt")&& [1, "<select
multiple='multiple'>","</select>"]
//<leg 必須在<fieldset>內(nèi)部
|| !tags.indexOf("<leg")&& [1, "<fieldset>", "</fieldset>"]
//thead|tbody|tfoot|colg|cap必須在<table>內(nèi)部
|| tags.match(/^<(thead|tbody|tfoot|colg|cap)/)
&& [1, "<table>", "</table>"]
//<tr在<tbody>中間
|| !tags.indexOf("<tr")&& [2, "<table><tbody>", "</tbody></table>"]
//td在tr中間
(!tags.indexOf("<td") || !tags.indexOf("<th"))&& [3,
"<table><tbody><tr>","</tr></tbody></table>"]
//col在<colgroup>中間
|| !tags.indexOf("<col")&& [2,
"<table><tbody></tbody><colgroup>","</colgroup></table>"]
//IE中 link script不能串行化 ?
|| jQuery.browser.msie&& [1, "div<div>", "</div>"]
//默認(rèn)不修正
|| [0, "", ""];
// 包裹html之后,采用innerHTML轉(zhuǎn)換成Dom
div.innerHTML = wrap[1] + elem + wrap[2];
聯(lián)系客服