標籤:
本系列文章導航
從零開始學習jQuery (三) 管理jQuery封裝集
一.摘要
在使用jQuery選取器擷取到jQuery封裝集後, 我們需要對其進行操作. 本章首先講解如何動態建立元素, 接著學習如何管理jQuery封裝集, 比如添加,刪除,切片等.
二.前言
本系列的2,3篇上面列舉了太多的API相信大家看著眼暈. 不過這些基礎還必須要講, 基礎要紮實.其實對於這些列表大家可以跳過, 等以後用到時再回頭看或者查詢官方的API說明.
本章內容很少, 主要講解動態建立元素和操作jQuery封裝集的各個函數.
三.動態建立元素1.錯誤的編程方法
我們經常使用javascript動態建立元素, 有很多程式員通過直接更改某一個容器的HTML內容.比如:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head> <title>動態建立對象</title></head><body><div id="testDiv">測試圖層</div><script type="text/javascript"> document.getElementById("testDiv").innerHTML = "<div style=\"border:solid 1px #FF0000\">動態建立的div</div>";</script></body></html>
上面的樣本中我通過修改testDiv的內容,在頁面上動態添加了一個div元素. 但是請牢記,這是錯誤的做法!
錯誤的原因:
(1) 在頁面載入時改變了頁面的結構. 在IE6中如果網路變慢或者頁面內容太大就會出現"終止操作"的錯誤. 也就是說"永遠不要在頁面載入時改變頁面的Dom模型".
(2) 使用修改HTML內容添加元素, 不符合Dom標準. 在實際工作中也碰到過使用這種方法修改內容後, 某些瀏覽器中並不能立刻顯示添加的元素, 因為不同瀏覽器的顯示引擎是不同的. 但是如果我們使用Dom的CreateElement建立對象, 在所有的瀏覽器中幾乎都可以. 但是在jQuery中如果傳入的而是一個完整的HTML字串, 內部也是使用innerHTML. 所以也不是完全否定innerHTML函數的使用.
所以從現在開始請摒棄這種舊知識, 使用下面介紹的正確方法編程.
2.建立新的元素
下面介紹兩種正確的建立元素的方式.
(1)使用HTML DOM建立元素
什麼是 DOM?
通過 JavaScript,您可以重構整個 HTML 文檔。您可以添加、移除、改變或重排頁面上的項目。
要改變頁面的某個東西,JavaScript 就需要對 HTML 文檔中所有元素進行訪問的入口。這個入口,連同對 HTML 元素進行添加、移動、改變或移除的方法和屬性,都是通過文件物件模型來獲得的(DOM)。
在 1998 年,W3C 發布了第一級的 DOM 規範。這個規範允許訪問和操作 HTML 頁面中的每一個單獨的元素。
所有的瀏覽器都執行了這個標準,因此,DOM 的相容性問題也幾乎難覓蹤影了。
DOM 可被 JavaScript 用來讀取、改變 HTML、XHTML 以及 XML 文檔。
DOM 被分為不同的部分(核心、XML及HTML)和層級(DOM Level 1/2/3):
-
Core DOM
-
定義了一套標準的針對任何結構化文檔的對象
-
XML DOM
-
定義了一套標準的針對 XML 文檔的對象
-
HTML DOM
-
定義了一套標準的針對 HTML 文檔的對象。
關於使用HTML DOM建立元素本文不做詳細介紹, 下面舉一個簡單的例子:
//使用Dom標準建立元素 var select = document.createElement("select"); select.options[0] = new Option("附加元件1", "value1"); select.options[1] = new Option("附加元件2", "value2"); select.size = "2"; var object = testDiv.appendChild(select);
通過使用 document.createElement 方法我們可以建立Dom元素, 然後通過appendChild方法為添加到指定對象上.
(2) 使用jQuery函數建立元素
在jQuery中建立對象更加簡單, 比如建立一個Div元素:
$("<div style=\"border:solid 1px #FF0000\">動態建立的div</div>")
我們主要使用jQuery核心類庫中的一個方法:
jQuery( html, ownerDocument )
Returns: jQuery
根據HTML原始字串動態建立Dom元素.
其中html參數是一個HTML字串, 在jQuery1.3.2中對此函數做了改進:
當HTML字串是沒有屬性的元素是, 內部使用document.createElement建立元素, 比如:
//jQuery內部使用document.createElement建立元素:$("<div/>").css("border","solid 1px #FF0000").html("動態建立的div").appendTo(testDiv);
否則使用innerHTML方法建立元素:
//jQuery內部使用innerHTML建立元素:$("<div style=\"border:solid 1px #FF0000\">動態建立的div</div>").appendTo(testDiv);3.將元素添加到對象上
我們可以使用上面兩種方式建立一個而元素, 但是上面已經提到一定不要在頁面載入時就改變頁面的DOM結構, 比如添加一個元素. 正確的做法是在頁面載入完畢後添加或刪除元素.
傳統上, 使用window.onload完成上述目的:
//DOM載入完畢後添加元素//傳統方法window.onload = function() { testDiv.innerHTML = "<div style=\"border:solid 1px #FF0000\">動態建立的div</div>"; }
雖然能夠在DOM完整載入後, 在添加新的元素, 但是不幸的是瀏覽器執行window.onload函數不僅僅是在構建完DOM樹之後, 也是在所有映像和其他外部資源完整的載入並且在瀏覽器視窗顯示完畢之後. 所以如果某個圖片或者其他資源載入很長時間, 訪問者就會看到一個不完整的頁面, 甚至在圖片載入之前就執行了需要依賴動態添加的元素的指令碼而導致指令碼錯誤.
解決辦法就是等DOM被解析後, 在映像和外部資源載入之前執行我們的函數.在jQuery中讓這一實現變得可行:
//jQuery 使用動態建立的$(document).ready(function)方法$(document).ready( function() { testDiv.innerHTML = "<div style=\"border:solid 1px #FF0000\">使用動態建立的$(document).ready(function)方法</div>"; });
或者使用簡便文法:
//jQuery 使用$(function)方法$( function() { testDiv.innerHTML += "<div style=\"border:solid 1px #FF0000\">使用$(function)方法</div>"; });
使用$()將我們的函數封裝起來即可. 而且可以在一個頁面綁定多個函數, 如果使用傳統的window.onload則只能調用一個函數.
所以請大家將修改DOM的函數使用此方法調用. 另外還要注意document.createElement和innerHTML的區別. 如果可以請盡量使用document.createElement和$("<div/>")的形式建立對象.
四.管理jQuery封裝集元素
既然學會了動態建立元素, 接下來就會想要把這些元素放入我們的jQuery封裝集中.
我們可以在jQuery封裝集上調用下面這些函數, 用來改變我們的原始jQuery封裝集, 並且大部分返回的都是過濾後的jQuery封裝集.
jQuery提供了一系列的函數用來管理組件裝集:
1.過濾 Filtering
| 名稱 |
說明 |
舉例 |
| eq( index ) |
擷取第N個元素 |
擷取匹配的第二個元素: $("p").eq(1) |
| filter( expr ) |
篩選出與指定運算式匹配的元素集合。 |
保留帶有select類的元素: $("p").filter(".selected") |
| filter( fn ) |
篩選出與指定函數傳回值匹配的元素集合 這個函數內部將對每個對象計算一次 (正如 ‘$.each‘). 如果調用的函數返回false則這個元素被刪除,否則就會保留。 |
保留子項目中不含有ol的元素:
$("div").filter(function(index) { return $("ol", this).size() == 0; }); |
is( expr )
注意: 這個函數返回的不是jQuery封裝集而是Boolean值 |
用一個運算式來檢查當前選擇的元素集合,如果其中至少有一個元素符合這個給定的運算式就返回true。 如果沒有元素符合,或者運算式無效,都返回‘false‘. ‘filter‘ 內部實際也是在調用這個函數,所以,filter()函數原有的規則在這裡也適用。 |
由於input元素的父元素是一個表單元素,所以返回true: $("input[type=‘checkbox‘]").parent().is("form") |
| map( callback ) |
將一組元素轉換成其他數組(不論是否是元素數組) 你可以用這個函數來建立一個列表,不論是值、屬性還是CSS樣式,或者其他特別形式。這都可以用‘$.map()‘來方便的建立 |
把form中的每個input元素的值建立一個列表:
$("p").append( $("input").map(function(){ return $(this).val(); }).get().join(", ") ); |
| not( expr ) |
刪除與指定運算式匹配的元素 |
從p元素中刪除帶有 select 的ID的元素: $("p").not( $("#selected")[0] ) |
slice( start, end ) |
選取一個匹配的子集 |
選擇第一個p元素: $("p").slice(0, 1); |
2.尋找 Finding
| 名稱 |
說明 |
舉例 |
| add( expr ) |
把與運算式匹配的元素添加到jQuery對象中。這個函數可以用於串連分別與兩個運算式匹配的元素結果集。 |
動態產生一個元素並添加至匹配的元素中: $("p").add("<span>Again</span>") |
| children( [expr] ) |
取得一個包含匹配的元素集合中每一個元素的所有子項目的元素集合。 可以通過可選的運算式來過濾所匹配的子項目。注意:parents()將尋找所有祖輩元素,而children()只考慮子項目而不考慮所有後代元素。 |
尋找DIV中的每個子項目: $("div").children() |
| closest( [expr] ) |
取得與運算式匹配的最新的父元素 |
為事件來源最近的父類li對象更換樣式: $(document).bind("click", function (e) { $(e.target).closest("li").toggleClass("hilight"); }); |
| contents( ) |
尋找匹配元素內部所有的子節點(包括文本節點)。如果元素是一個iframe,則尋找文檔內容 |
尋找所有文本節點並加粗: $("p").contents().not("[nodeType=1]").wrap("<b/>"); |
| find( expr ) |
搜尋所有與指定運算式匹配的元素。這個函數是找出正在處理的元素的後代元素的好方法。 所有搜尋都依靠jQuery運算式來完成。這個運算式可以使用CSS1-3的選取器文法來寫。 |
從所有的段落開始,進一步搜尋下面的span元素。與$("p span")相同: $("p").find("span") |
| next( [expr] ) |
取得一個包含匹配的元素集合中每一個元素緊鄰的後面同輩元素的元素集合。 這個函數只返回後面那個緊鄰的同輩元素,而不是後面所有的同輩元素(可以使用nextAll)。可以用一個可選的運算式進行篩選。 |
找到每個段落的後面緊鄰的同輩元素: $("p").next() |
| nextAll( [expr] ) |
尋找當前元素之後所有的同輩元素。 可以用運算式過濾 |
給第一個div之後的所有元素加個類: $("div:first").nextAll().addClass("after"); |
| offsetParent( ) |
返回第一個有定位的父類(比如(relative或absolute)). |
|
| parent( [expr] ) |
取得一個包含著所有匹配元素的唯一父元素的元素集合。 你可以使用可選的運算式來篩選。 |
尋找每個段落的父元素: $("p").parent() |
| parents( [expr] ) |
取得一個包含著所有匹配元素的祖先元素的元素集合(不包含根項目)。可以通過一個可選的運算式進行篩選。 |
找到每個span元素的所有祖先元素: $("span").parents() |
| prev( [expr] ) |
取得一個包含匹配的元素集合中每一個元素緊鄰的前一個同輩元素的元素集合。 可以用一個可選的運算式進行篩選。只有緊鄰的同輩元素會被匹配到,而不是前面所有的同輩元素。 |
找到每個段落緊鄰的前一個同輩元素: $("p").prev() |
| prevAll( [expr] ) |
尋找當前元素之前所有的同輩元素 可以用運算式過濾。 |
給最後一個之前的所有div加上一個類: $("div:last").prevAll().addClass("before"); |
| siblings( [expr] ) |
取得一個包含匹配的元素集合中每一個元素的所有唯一同輩元素的元素集合。可以用可選的運算式進行篩選。 |
找到每個div的所有同輩元素: $("div").siblings() |
3.串聯 Chaining
| 名稱 |
說明 |
舉例 |
| andSelf( ) |
加入先前所選的加入當前元素中 對於篩選或尋找後的元素,要加入先前所選元素時將會很有用。 |
選取所有div以及內部的p,並加上border類: $("div").find("p").andSelf().addClass("border"); |
| end( ) |
回到最近的一個"破壞性"操作之前。即,將匹配的元素列表變為前一次的狀態。
如果之前沒有破壞性操作,則返回一個空集。所謂的"破壞性"就是指任何改變所匹配的jQuery元素的操作。這包括在 Traversing 中任何返回一個jQuery對象的函數--‘add‘, ‘andSelf‘, ‘children‘, ‘filter‘, ‘find‘, ‘map‘, ‘next‘, ‘nextAll‘, ‘not‘, ‘parent‘, ‘parents‘, ‘prev‘, ‘prevAll‘, ‘siblings‘ and ‘slice‘--再加上 Manipulation 中的 ‘clone‘。 |
選取所有的p元素,尋找並選取span子項目,然後再回過來選取p元素:
$("p").find("span").end() |
五.常用函數舉例
[待續]
六.總結
本篇文章內容較少, 主要講解如何動態建立元素以及管理jQuery封裝集, 介面文檔列舉了太多, 執行個體部分還沒來得及寫. 因為要睡覺明天還要上班, 所以請各位見諒, 等以後有空的時候補上!
從零開始學習jQuery (三) 管理jQuery封裝集