動態創建元素:摒棄 innerHTML,擁抱標準
錯誤示範
// 錯誤:頁面載入時修改 innerHTML,易導致 IE「終止操作」、違反 DOM 標準、事件綁定丟失
document.getElementById("container").innerHTML = "新內容
";
正確方式一:原生 DOM API
var div = document.createElement("div");
div.textContent = "新內容";
document.getElementById("container").appendChild(div);
正確方式二:jQuery 工廠函數 $()
// 1. 簡單標籤 (內部用 createElement,效能最佳)
$("").text("新內容").appendTo("#container");
// 2. 複雜 HTML 字串 (內部用 innerHTML)
$("
內容
").appendTo("#container");
// 3. 指定屬性建立 (1.4+)
$("
", {
href: "https://example.com",
target: "_blank",
text: "連結",
class: "btn",
click: function(e) { track("click"); }
}).appendTo("#nav");
頁面就緒時機:$(document).ready()
// 標準寫法
$(document).ready(function() { /* DOM 就緒,圖片未必載入完 */ });
// 簡寫 (推薦)
$(function() { /* 同上 */ });
// 多個 ready 會依序執行,優於 window.onload (需等圖片/資源)
window.onload = function() { /* 所有資源載入完 */ };
包裝集管理核心 API 分類
1. 存取與轉換
| 方法 | 說明 | 回傳 |
.get() | 取得原生陣列 | Array |
.get(index) | 取得單個 DOM 元素 | Element / undefined |
[index] | 直接索引取得 DOM 元素 | Element |
.toArray() | 同 .get() | Array |
.index() | 元素在包裝集/同輩中的索引 | Number |
2. 篩選 Filtering (最常用)
| 方法 | 說明 | 範例 |
.eq(index) | 取得第 N 個 (負數從後) | $("li").eq(0) 第一個 |
.first() / .last() | 首/尾元素 | $("li").first() |
.slice(start, end) | 切片 [start, end) | $("li").slice(1,3) 第2,3個 |
.filter(selector|fn) | 保留符合條件者 | $("li").filter(".active") / .filter(function(){ return $(this).text().length>5; }) |
.not(selector|fn|element) | 移除符合條件者 (反 filter) | $("li").not(".active") |
.has(selector|element) | 保留包含特定後代的元素 | $("li").has("ul") |
.is(selector|fn|element) | 檢查是否符合,**回傳布林** | if ($(this).is(".active")) ... |
.map(fn) | 映射轉換,回傳新包裝集 | $("input").map(function(){ return this.value; }) |
3. 尋找後代/祖先/同輩 (遍歷)
| 方法 | 方向 | 說明 |
.find(selector) | 後代 | **最常用**,深度搜尋後代 |
.children(selector) | 子代 | 僅直接子元素 |
.parent(selector) | 父代 | 單層父元素 |
.parents(selector) | 祖先 | 所有祖先至 html,可篩選 |
.parentsUntil(selector) | 祖先 | 直到符合選擇器為止 |
.closest(selector) | 祖先 | **從自身向上找第一個符合** (含自身),極常用於委派事件中找容器 |
.siblings(selector) | 同輩 | 所有兄弟元素 |
.next() / .nextAll() / .nextUntil() | 後同輩 | 下一個/所有後面/直到 |
.prev() / .prevAll() / .prevUntil() | 前同輩 | 上一個/所有前面/直到 |
4. 添加與合併
.add(selector|elements|html):將新元素加入包裝集 (去重)。
.addBack() (1.8+):加入前一次操作前的包裝集 (舊 .andSelf() 棄用)。
.contents():取得子節點 (含文字節點),iframe 可取得文檔。
5. 迭代與鏈式控制
.each(function(index, element) {
// this === element (原生 DOM)
// return false 終止迴圈 (break)
// return true 繼續下一個 (continue)
});
// 終結鏈式,回傳上一個包裝集
$("div").find("span").addClass("hi").end().addClass("container");
實戰範例:動態產生表格並綁定事件委派
function renderUserTable(users) {
var $tbody = $("#userTable tbody").empty();
var $frag = $(document.createDocumentFragment()); // 文檔片段,批量掛載後一次重繪
$.each(users, function(i, user) {
var $tr = $("", { "data-id": user.id }).append(
$("| ").text(user.name),
$(" | ").text(user.email),
$(" | ").append(
$(" |