| 方法 | 返回值 | 性能 | 適用場景 |
|---|---|---|---|
document.getElementById(id) | 單一 Element | 最快 | 精確定位唯一元素 |
element.getElementsByTagName(tag) | 即時 HTMLCollection | 快 | 批量操作同類標簽 |
document.getElementsByClassName(class) | 即時 HTMLCollection | 中等 | 按樣式類查找,IE9+ 支持 |
document.querySelector(selector) | 首個匹配 Element | 較慢 | 複雜 CSS 選擇器 |
document.querySelectorAll(selector) | 靜態 NodeList | 較慢 | 需靜態列表/複雜選擇器 |
// 1. 內容操作
element.innerHTML = '新內容'; // 解析 HTML,有 XSS 風險
element.textContent = '純文本內容'; // 安全,不解析 HTML
element.value = '輸入框值'; // 表單元素專用
// 2. 屬性操作
element.setAttribute('data-id', '100'); // 設置任意屬性
element.getAttribute('href'); // 獲取屬性原始值
element.dataset.userId = '100'; // HTML5 data-* 屬性快捷訪問
element.removeAttribute('disabled'); // 移除屬性
// 3. 樣式操作
element.style.color = 'blue'; // 行內樣式,高優先級
element.style.cssText = 'color:red;font-size:14px;'; // 批量設置
element.classList.add('active'); // 類名操作(推薦)
element.classList.toggle('hidden'); // 切換類名
element.classList.contains('disabled'); // 判斷類名
// 創建元素
const div = document.createElement('div');
div.className = 'card';
div.innerHTML = '標題
內容
';
// 插入位置控制
parent.appendChild(div); // 末尾子節點
parent.insertBefore(div, referenceNode); // 指定節點前
parent.prepend(div); // 首個子節點 (現代 API)
referenceNode.after(div); // 緊隨其後 (現代 API)
// 刪除
div.remove(); // 現代 API
// 或 parent.removeChild(div); // 傳統方式
絕大多數事件(click, keydown 等)支持冒泡;focus, blur, load, unload 等不冒泡。
| 方式 | 代碼示例 | 優點 | 缺點 |
|---|---|---|---|
| HTML 內聯 | <button onclick="fn()"> | 直觀 | 結構行為耦合、作用域污染、難維護 |
| DOM 0 級 | btn.onclick = fn | 簡單、兼容性好 | 同一事件只能綁一個處理器 |
| DOM 2 級 (推薦) | btn.addEventListener('click', fn, false) | 多處理器、可控捕獲/冒泡、可移除、支持選項對象 | IE8- 需 attachEvent |
element.addEventListener('click', function(event) {
// 兼容寫法:event = event || window.event;
event.type; // 'click'
event.target; // 觸發事件的實際元素
event.currentTarget; // 綁定事件的元素 (=== this)
event.clientX/Y; // 相對視口座標
event.pageX/Y; // 相對文檔座標
event.key; // 按鍵值 (鍵盤事件)
event.preventDefault(); // 阻止默認行為 (如表單提交、鏈接跳轉)
event.stopPropagation(); // 阻止冒泡
event.stopImmediatePropagation(); // 阻止同元素其他處理器執行
});
// 錯誤:為 1000 個 li 綁定點擊 → 內存/性能差
// document.querySelectorAll('li').forEach(li => li.onclick = fn);
// 正確:委托給父級 ul
document.getElementById('list').addEventListener('click', function(e) {
if (e.target.tagName === 'LI') {
console.log('點擊了:', e.target.textContent);
}
});
// ES Modules (瀏覽器原生支持)
export const API_BASE = '/api/v1';
export function fetchUser(id) { return fetch(`${API_BASE}/users/${id}`).then(r => r.json()); }
// 導入
import { API_BASE, fetchUser } from './api.js';
// IIFE 兼容舊環境
const MyModule = (function() {
const privateVar = 'secret';
return { publicMethod() { console.log(privateVar); } };
})();
// 並發請求
const [users, posts] = await Promise.all([
fetch('/api/users').then(r => r.json()),
fetch('/api/posts').then(r => r.json())
]);
// 超時控制
const response = await Promise.race([
fetch('/api/slow'),
new Promise((_, reject) => setTimeout(() => reject(new Error('Timeout')), 5000))
]);
// 錯誤邊界處理
try {
const data = await fetchData();
} catch (err) {
console.error('請求失敗:', err);
showErrorUI(err.message);
}
requestAnimationFrame 做動畫,避免 setIntervalconst debounced = debounce(fn, 300) (輸入框搜索)const throttled = throttle(fn, 100) (滾動/縮放監聽)removeEventListener,避免內存洩漏loading="lazy")DocumentFragmenttextContent 代替 innerHTML,CSP 標頭,輸出編碼X-Frame-Options: DENY 或 Content-Security-Policy: frame-ancestors 'none'JavaScript 已從「頁面腳本」進化為「全棧應用語言」。掌握 DOM 本質、事件流機制、異步模式與工程化工具鏈,是構建健壯、高性能、可維護前端應用的基石。