2016年5月2日 星期一

jQuery Object

jQuery Object

簡介

用過 jQuery 的人都熟悉 $(selector, context) 這個語法,並用它來搜尋 context 這個指定範圍中符合 selector 所描述的所有元件。許多初學者常誤認傳回值是一個包含了符合條件的 DOM 元件陣列;實則不然,它的傳回值其實是一個包含了 jQuery Object 的集合 ( collection)。這篇就探究這個傳回的集合,以及其中所包含的 jQuery Object。

首先,我們得區分 DOM 元件和 jQuery Object 有何不同。DOM 元件一般被視為整篇 HTML 文件中的一小片段,在使用時得透過 DOM 的 javascript API 來運作,像是 var target = document.getElementById("target"); 以取得 id="target" 的 DOM 元件。在 jQuery 裡,則用 $("#target") 來取得 jQuery Object,這個 jQuery Object (實質上就是一個 Javascript 的物件),其中含有 id="target" 的 DOM 元件,和許多 jQuery 為這個物件擴充的函式,像是 html(), text(), css() 。。。等等。使用 jQuery Object 的函式來運作 DOM tree 有很多的優點,例如程式碼比較精簡,功能可以跨流覧器等等。能夠區分 DOM 元件和 jQuery Object 的不同在撰寫程式時是很重要的,這樣才能知道那些物件具有 jQuery 的函式可以呼叫,那些物件只是單純的 DOM 元件,並不具有 jQuery 函式。

其次,我們看看 jQuery 是如何建立 jQuery Object。當 $(selector, context) 被呼叫時,jQuery 便從 DOM tree 中搜尋符合 selector 條件的 DOM 元件,每搜尋到一個符合的元件,便將其包覆在一個 jQuery Object 中,以 DOM 元件的 tag, id 及 class 的值組合成 jQuery Object 的名稱,並將其加入要傳回的集合 (collection) 中。此外,這個集合還包含了另外三個屬性:

prevObject
prevObject 的值是一個指標 (pointer),它的值指到上一個搜尋的結果,這是 jQuery 內部在使用的指標,end() 函式就是靠這個屬性值回遡到上一次搜尋的結果。
context
context 的值也是個指標 (pointer) 指到本次搜尋的範圍。也就是 $(selector, context) 中 context 參數的賦予值,如果沒給 context 參數,則預設為指向 document。
selector
selector 的值是一字串,也就是 $(selector, context) 中 selector 參數的賦予值。
其它部份,看程式碼的說明。

範例

範例中在流覧器中顯示兩個方塊,表示 HTML 文件已下載完畢,可以進到「開發者工具」的「主控台」去看範例輸出的結果,在不同的流覧器的主控台中,輸出的格式略有不同,在 Chrome 中,某些輸出格式有時會讓人分不清是物件還是陣列,這點也很惱人,只能說:「習慣就好!」Firefox 的輸出就明確的多,連指標 (pointer) 都標示的很清礎。

CSS

<style>
html {
 width:100%;
 height:100%;
}
body {
 margin:0 auto;
 width:1000px;
 height:100%;
 padding-top:20px;
}
.box {
    margin:10px;
    width:100px;
    height:100px;
    background-color: coral;
}
</style>

CSS 中,.box{} 定義兩個方塊的外觀,只是用來顯示 HTML 文件已經下載完畢。

HTML

<body>
    
</body>

HTML 中很簡單的定義了兩個 <div>,用來顯示方塊和做為搜尋元件之用。

Script

<script>
$(function(){
    // retrieve the jquery version number
    console.log("jQuery version is %s", $.fn.jquery);
    var elem = $("div");

    // elem is a collection, not an Array
    console.log("elem = %o", elem);
    console.log("elem.length = %d", elem.length); // 2
    console.log(Array.isArray(elem));             // false

    // elem.prevObject is a function, returns previous matched result  
    console.log("elem.prevObject = %o", elem["prevObject"]); 
    console.log("elem.prevObject = %o", elem.prevObject);
    console.log("elem.context = %o", elem.context);
    console.log("elem.selector = %o", elem.selector);

    console.log("DOM Element");
    // return all matched elements as an array
    console.log("\t %o", elem.get());

    // the following expressions return the same result
    console.log("\t %o", elem.get(0));
    console.log("\t %o", elem.get(-1));
    console.log("\t %o", elem[0]);
    console.log("\t %o", elem["0"]);

    console.log("jQuery Object")
    console.log("\t %o", elem.eq(0));
    console.log("\t %o", elem.eq());
});
</script>

第 4 行,印出目前使用的 jQuery 版本。
第 5 行,進行一次搜尋,條件為標記為 div 的所有元件。
第 6 行,輸出搜尋後的傳回集合 (collection),內中的各元素所代表的意思,在前面都有解釋了。
第 7 行,輸出符合條件的元件數,如果搜尋不到任何符合條件的元件,這個值就會是 0,可以用這個數值來判斷是否有搜尋到符合條件的元件。
第 8 行,輸出值為 false,證明傳回值並不是個陣列型態的物件。
第 13~16 行,輸出 prevObject, context, 及 selector 的屬性值。第 13 行及第 14 行顯示兩種不同取得屬性值的方法。
第20 行,將所有符合條件的元件,包裝成 jQuery Object 後,以陣列的方式傳回。這裡的傳回值就真的是個陣列了。
第23~26 行,用各種不同的方式取得 DOM 元件,用 get(number) 的好處是 number 參數可以傳入負值,由未端起算,取回元件。
第 29 行,取回第一個 jQuery Object。注意:get() 傳回的是 jQuery Object 的陣列,get(number) 傳回的是 DOM 元件,eq(number) 傳回的是 jQuery Object,別混淆了。特別是 get() 有給參數和沒給參數時,傳回的物件完全不一樣,最容易出錯。eq() 沒給參數時,則傳回的物件中不含任何 jQuery Object,length 值為 0。

沒有留言:

張貼留言