本系列文章導航 從零開始學習jQuery (三) 管理jQuery包裝集 一.摘要 在使用jQuery選擇器獲取到jQuery包裝集後, 我們需要對其進行操作. 本章首先講解如何動態的創建元素, 接著學習如何管理jQuery包裝集, 比如添加,刪除,切片等. 二.前言 本系列的2,3篇上面列舉了太多 ...
本系列文章導航
一.摘要
在使用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) { |
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(){ |
not( expr ) | 刪除與指定表達式匹配的元素 | 從p元素中刪除帶有 select 的ID的元素: $("p").not( $("#selected")[0] ) |
選取一個匹配的子集 | 選擇第一個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) { |
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包裝集, 介面文檔列舉了太多, 實例部分還沒來得及寫. 因為要睡覺明天還要上班, 所以請各位見諒, 等以後有空的時候補上!