30 KiB
Terrarium 專案第三部分:DOM 操作與 JavaScript 閉包
journey
title 你的 JavaScript DOM 旅程
section 基礎
了解 DOM: 3: Student
學習閉包: 4: Student
連接元素: 4: Student
section 互動
設置拖放事件: 4: Student
跟蹤座標: 5: Student
處理移動: 5: Student
section 精修
添加清理: 4: Student
測試功能: 5: Student
完成陸地生態箱: 5: Student
筆記作者 Tomomi Imura
歡迎來到網頁開發中最有趣的部分 —— 讓網頁變得互動!文件物件模型(DOM)就像 HTML 與 JavaScript 之間的橋樑,今天我們將利用它讓你的玻璃花房活起來。當 Tim Berners-Lee 創造第一個瀏覽器時,他設想了一個文件可以是動態且互動的網頁 —— DOM 讓這個願景成真。
我們還會探討 JavaScript 閉包,這個詞一開始可能聽起來嚇人。把閉包想像成幫你的函式製造「記憶口袋」,能記住重要資訊。就像你玻璃花房裡的每株植物都有自己的資料紀錄,追蹤位置。完成這堂課後,你會發現它們是多麼自然且實用。
現在我們要打造的是:一個使用者能自由拖放植物到任何位置的玻璃花房。你會學會 DOM 操作技巧,這些技巧是從拖放檔案上傳到互動遊戲的基礎。讓我們讓你的玻璃花房活起來吧。
mindmap
root((DOM & JavaScript))
DOM 樹
元素選取
屬性存取
事件處理
動態更新
事件
指標事件
滑鼠事件
觸控事件
事件監聽器
閉包
私有變數
函式作用域
記憶體持續性
狀態管理
拖放
位置追蹤
座標計算
事件生命週期
使用者互動
現代模式
事件委派
效能
跨裝置
無障礙
課前小測驗
認識 DOM:你的互動式網頁大門
文件物件模型(DOM)是 JavaScript 與你的 HTML 元素溝通的方式。當瀏覽器載入 HTML 頁面時,它會在記憶體中建立該頁的結構化表示 —— 這就是 DOM。你可以將它想成一棵家譜樹,每個 HTML 元素都是家族成員,JavaScript 能造訪、修改或重排它們。
DOM 操作可以將靜態網頁轉變為互動式網站。你每次看到按鈕在滑鼠懸停時變色、內容更新不需重新整理頁面,或元素可拖曳移動,背後都是 DOM 操作的功勞。
flowchart TD
A["文件"] --> B["HTML"]
B --> C["標頭"]
B --> D["主體"]
C --> E["標題"]
C --> F["元標籤"]
D --> G["H1: 我的生態箱"]
D --> H["Div: 頁面容器"]
H --> I["Div: 左側容器"]
H --> J["Div: 右側容器"]
H --> K["Div: 生態箱"]
I --> L["植物元素 1-7"]
J --> M["植物元素 8-14"]
L --> N["img#plant1"]
L --> O["img#plant2"]
M --> P["img#plant8"]
M --> Q["img#plant9"]
style A fill:#e1f5fe
style B fill:#f3e5f5
style D fill:#e8f5e8
style H fill:#fff3e0
style N fill:#ffebee
style O fill:#ffebee
style P fill:#ffebee
style Q fill:#ffebee
DOM 與參照它的 HTML 標記的表示圖。取自 Olfa Nasraoui
DOM 強大的原因:
- 提供有結構的方式存取頁面上任意元素
- 允許動態更新內容而不需重新整理頁面
- 支持對點擊與拖曳等用戶互動即時回應
- 奠定現代互動網頁應用的根基
JavaScript 閉包:打造有組織且強大的程式碼
JavaScript 閉包就像給函式一個專屬的私有工作區,擁有持續的記憶能力。設想達爾文的加拉帕戈斯群島雀鳥根據環境發展出專屬的喙 —— 閉包同理,創造專屬功能,即使父函式執行完,仍記住特定上下文。
在我們的玻璃花房中,閉包幫助每株植物獨立記憶自己的位置。這個模式在專業 JavaScript 開發中無處不在,是值得理解的重要概念。
flowchart LR
A["dragElement(plant1)"] --> B["建立閉包"]
A2["dragElement(plant2)"] --> B2["建立閉包"]
B --> C["私有變數"]
B2 --> C2["私有變數"]
C --> D["pos1, pos2, pos3, pos4"]
C --> E["pointerDrag 函式"]
C --> F["elementDrag 函式"]
C --> G["stopElementDrag 函式"]
C2 --> D2["pos1, pos2, pos3, pos4"]
C2 --> E2["pointerDrag 函式"]
C2 --> F2["elementDrag 函式"]
C2 --> G2["stopElementDrag 函式"]
H["植物1記住它的位置"] --> B
H2["植物2記住它的位置"] --> B2
style B fill:#e8f5e8
style B2 fill:#e8f5e8
style C fill:#fff3e0
style C2 fill:#fff3e0
💡 認識閉包:閉包是 JavaScript 重要議題,許多開發者花好幾年才完全理解其理論面。今天我們重點在實際應用——隨著互動功能開發,閉包會自然出現。理解會隨觀察實際解決問題過程逐漸建立。
DOM 與參照它的 HTML 標記的表示圖。取自 Olfa Nasraoui
這堂課,我們將完成互動玻璃花房專案,撰寫讓使用者能操作頁面中植物的 JavaScript。
開始前:做好準備迎接成功
你需要先前玻璃花房課程的 HTML 與 CSS 檔案 —— 我們將讓這個靜態設計變成可互動的。如果你是第一次加入,建議先完成之前的課程以取得重要背景。
我們將打造:
- 所有植物的 平滑拖放功能
- 位置的 座標追蹤 識別植物記憶位置
- 使用純原生 JavaScript 實作的 完整互動介面
- 運用閉包模式維持的 乾淨有組織程式碼
設定你的 JavaScript 檔案
來建立一個讓玻璃花房可互動的 JavaScript 檔案。
第一步:建立腳本檔案
在你的 terrarium 資料夾中,建立一個名為 script.js 的新檔案。
第二步:將 JavaScript 連結至你的 HTML
在 index.html 的 <head> 區段加入以下 script 標籤:
<script src="./script.js" defer></script>
為何 defer 屬性很重要:
- 確保你的 JavaScript 等待全部 HTML 載入完成
- 避免JavaScript 嘗試取用尚未準備好的元素而產生錯誤
- 確保所有植物元素都可被互動使用
- 比放在頁尾執行有更好的效能
⚠️ 重要提醒:
defer屬性可避免常見的時間點問題。若沒用它,JavaScript 可能搶先於 HTML 載入前存取元素,導致錯誤。
將 JavaScript 與 HTML 元素連結
在讓元素可拖放之前,JavaScript 需要先找到它們在 DOM 中的位置。這就像圖書館的分類系統 —— 有了編號,就能精準找到你要的書,並取得其所有內容。
我們會先用 document.getElementById() 方法進行對應。這就像有個精準的文件夾編號系統 —— 傳入 ID,即能精準定位 HTML 中的元素。
啟用所有植物拖曳功能
在你的 script.js 中加入這段程式碼:
// 啟用所有14個植物的拖曳功能
dragElement(document.getElementById('plant1'));
dragElement(document.getElementById('plant2'));
dragElement(document.getElementById('plant3'));
dragElement(document.getElementById('plant4'));
dragElement(document.getElementById('plant5'));
dragElement(document.getElementById('plant6'));
dragElement(document.getElementById('plant7'));
dragElement(document.getElementById('plant8'));
dragElement(document.getElementById('plant9'));
dragElement(document.getElementById('plant10'));
dragElement(document.getElementById('plant11'));
dragElement(document.getElementById('plant12'));
dragElement(document.getElementById('plant13'));
dragElement(document.getElementById('plant14'));
這段程式碼的目的:
- 尋找 DOM 中每個植物元素的獨特 ID
- 取得每個 HTML 元素的 JavaScript 引用
- 將元素傳入即將建立的
dragElement函式處理 - 準備每株植物支援拖放互動
- 連結你的 HTML 結構與 JavaScript 功能
🎯 為什麼用 ID 而非 Class? ID 提供每個特定元素獨一無二的識別,CSS Class 則適合用來設計多個元素的樣式。JavaScript 需要精準操控個別元素時,ID 提供了必要的精確性與效能。
💡 專家小提示:你會注意到程式碼為每株植物單獨呼叫
dragElement()。這確保每株植物擁有獨立拖放行為,這對流暢的使用者體驗至關重要。
🔄 教學檢視點
DOM 連結理解:進入拖曳功能前,確保你會:
- ✅ 解釋
document.getElementById()如何定位 HTML 元素 - ✅ 理解為何每株植物要有獨立的唯一 ID
- ✅ 描述
defer屬性的作用 - ✅ 識別 JavaScript 與 HTML 是如何經由 DOM 連結起來的
快速自我測驗:如果兩個元素有相同 ID,會發生什麼?為什麼 getElementById() 只會回傳一個元素?
答案:ID 必須唯一,若重複只會回傳第一個
建立拖曳元素閉包
現在我們將打造拖曳功能的核心:一個管理拖曳行為的閉包。這個閉包包含多個內部函式,協同監控滑鼠移動並更新元素位置。
閉包非常適合此任務,因為它讓我們能建立「私有」變數,跨多次函式呼叫持續存在,讓每株植物擁有獨立的座標追蹤系統。
用簡單例子了解閉包
我用一個簡單例子來示範閉包概念:
function createCounter() {
let count = 0; // 這就像一個私有變數
function increment() {
count++; // 內部函數記住了外部變數
return count;
}
return increment; // 我們回傳內部函數
}
const myCounter = createCounter();
console.log(myCounter()); // 1
console.log(myCounter()); // 2
這個閉包模式的重點:
- 建立一個私有的
count變數,只存在於閉包中 - 內部函式能存取並修改封閉外層的變數(閉包機制)
- 當回傳內部函式時,它仍然保有對該私有資料的連結
- 即使
createCounter()執行結束,count仍持續存在並記憶值
為什麼閉包最適合拖曳功能
每株植物都要記得自己目前位置座標。閉包為我們的專案帶來完美解決方案:
對我們專案的關鍵優點:
- 保持每株植物私有的座標變數
- 保存拖曳事件間的坐標資料
- 避免不同可拖曳元素間的變數衝突
- 製造乾淨且有組織的程式碼結構
🎯 學習目標:你不需立刻掌握閉包的全部細節。重點是了解閉包怎麼幫助我們組織程式和維持拖曳狀態。
stateDiagram-v2
[*] --> Ready: 頁面載入
Ready --> DragStart: 使用者按下(pointerdown)
DragStart --> Dragging: 滑鼠/手指移動(pointermove)
Dragging --> Dragging: 繼續移動
Dragging --> DragEnd: 使用者放開(pointerup)
DragEnd --> Ready: 重設以便下一次拖曳
state DragStart {
[*] --> CapturePosition
CapturePosition --> SetupListeners
SetupListeners --> [*]
}
state Dragging {
[*] --> CalculateMovement
CalculateMovement --> UpdatePosition
UpdatePosition --> [*]
}
state DragEnd {
[*] --> RemoveListeners
RemoveListeners --> CleanupState
CleanupState --> [*]
}
建立 dragElement 函式
現在來建立主要處理所有拖曳邏輯的函式。將這個函式放在你的植物元素宣告後面:
function dragElement(terrariumElement) {
// 初始化位置追蹤變數
let pos1 = 0, // 先前的滑鼠 X 位置
pos2 = 0, // 先前的滑鼠 Y 位置
pos3 = 0, // 當前的滑鼠 X 位置
pos4 = 0; // 當前的滑鼠 Y 位置
// 設定初始拖曳事件監聽器
terrariumElement.onpointerdown = pointerDrag;
}
認識位置追蹤系統:
pos1和pos2:記錄舊滑鼠與新滑鼠位置差異pos3和pos4:追蹤當前滑鼠座標terrariumElement:該可拖曳的植物元素onpointerdown:使用者開始拖曳時觸發的事件
閉包模式運作原理:
- 為每株植物元素建立私有位置變數
- 維持維護這些變數於拖曳生命週期中
- 確保每株植物獨立追蹤各自座標
- 透過
dragElement函式提供乾淨介面
為什麼用 Pointer 事件?
你可能會問為什麼用 onpointerdown 而不是熟悉的 onclick。原因如下:
| 事件類型 | 適用場景 | 注意事項 |
|---|---|---|
onclick |
簡單按鈕點擊 | 只能處理點擊並放開,無法拖曳 |
onpointerdown |
支援滑鼠與觸控 | 新式,但當前已廣泛支持 |
onmousedown |
僅桌面滑鼠 | 不支援行動裝置觸控 |
Pointer 事件適合我們的原因:
- 無論使用滑鼠、手指或觸控筆都可良好運作
- 在筆電、平板、手機上有一致操作體驗
- 能處理真正的拖曳動作,而非僅點擊
- 提供現代網頁應用期待的流暢體驗
💡 前瞻未來:Pointer 事件是現代用戶互動處理的標準,無需為滑鼠和觸控編寫兩套程式碼,超方便。
🔄 教學檢視點
事件處理理解:停下來確認你是否懂得:
- ✅ 為什麼用 pointer 事件而非 mouse 事件?
- ✅ 閉包變數如何在函式呼叫間持續存在?
- ✅
preventDefault()在平滑拖曳中扮演什麼角色? - ✅ 為何事件監聽器綁在 document 而非單一元素?
實務連結:想想你每天用的拖放介面:
- 檔案上傳:把檔案拖進瀏覽器視窗
- 看板系統:在欄位間移動任務卡
- 圖片庫:調整照片排序
- 行動介面:觸控螢幕滑動拖曳
pointerDrag 函式:捕捉拖曳開始
當使用者按下某株植物(無論用滑鼠或手指點擊),pointerDrag 函式會啟動。它擷取初始座標並設定拖曳系統。
將這個函式放在你的 dragElement 閉包內,位置在這段 terrariumElement.onpointerdown = pointerDrag; 行之後:
function pointerDrag(e) {
// 防止預設瀏覽器行為(如文字選取)
e.preventDefault();
// 捕捉初始滑鼠/觸控位置
pos3 = e.clientX; // 拖曳開始時的 X 座標
pos4 = e.clientY; // 拖曳開始時的 Y 座標
// 設置拖曳過程的事件監聽器
document.onpointermove = elementDrag;
document.onpointerup = stopElementDrag;
}
逐步說明:
- 阻止防止瀏覽器默認行為干擾拖曳
- 紀錄使用者開始拖曳時的精確座標
- 設定持續拖曳移動的事件監聽器
- 準備系統追蹤整個文件上的滑鼠/觸控移動
了解事件阻止
e.preventDefault() 是平滑拖曳的重要一行:
若不阻止,瀏覽器可能會:
- 在拖曳時選取頁面文字
- 在右鍵拖曳時彈出上下文選單
- 干擾我們自訂的拖曳行為
- 產生視覺上的拖曳異常
🔍 實驗:結束課程後試著移除
e.preventDefault(),感受一下拖曳行為的差異。你將會很快體會它的重要性!
座標追蹤系統
屬性 e.clientX 與 e.clientY 提供精確滑鼠/觸控位置:
| 屬性 | 測量內容 | 使用情境 |
|---|---|---|
clientX |
相對視窗的水平位置 | 追蹤左右移動 |
clientY |
相對視窗的垂直位置 | 追蹤上下移動 |
| 理解這些座標: |
- 提供 完美像素的定位資訊
- 隨著 使用者移動指標即時更新
- 在不同螢幕尺寸和縮放級別下仍保持 一致性
- 讓 拖曳操作流暢且反應迅速
設置文件級事件監聽器
請注意我們將移動和停止事件附加到整個 document,而不僅是植物元素:
document.onpointermove = elementDrag;
document.onpointerup = stopElementDrag;
為何附加到 document:
- 即使滑鼠離開植物元素也繼續 追蹤
- 防止 使用者快速移動時拖曳中斷
- 提供 整個螢幕的平滑拖曳體驗
- 處理 游標移出瀏覽器視窗的邊緣案例
⚡ 效能提醒:拖曳停止時我們會清除這些文件級監聽器,以避免記憶體洩漏和效能問題。
完成拖曳系統:移動與清理
現在我們將新增兩個函式,分別處理真正的拖曳移動和拖曳停止時的清理。這些函式協同工作,創造平滑且靈敏的植物移動體驗。
elementDrag 函式:追蹤移動
在 pointerDrag 函式的結尾大括號後新增 elementDrag 函式:
function elementDrag(e) {
// 計算自上次事件以來移動的距離
pos1 = pos3 - e.clientX; // 水平方向移動的距離
pos2 = pos4 - e.clientY; // 垂直方向移動的距離
// 更新目前位置追蹤
pos3 = e.clientX; // 新的目前 X 位置
pos4 = e.clientY; // 新的目前 Y 位置
// 將移動套用到元素的位置
terrariumElement.style.top = (terrariumElement.offsetTop - pos2) + 'px';
terrariumElement.style.left = (terrariumElement.offsetLeft - pos1) + 'px';
}
理解座標計算:
pos1和pos2:計算滑鼠自上一更新以來的移動距離pos3和pos4:儲存當前滑鼠位置以供下次計算offsetTop和offsetLeft:取得元素當前在頁面上的位置- 減法邏輯:依滑鼠移動距離來移動元素
sequenceDiagram
participant User
participant Mouse
participant JavaScript
participant Plant
User->>Mouse: 在 (100, 50) 開始拖曳
Mouse->>JavaScript: pointerdown 事件
JavaScript->>JavaScript: 儲存初始位置 (pos3=100, pos4=50)
JavaScript->>JavaScript: 設定移動/放開監聽器
User->>Mouse: 移動到 (110, 60)
Mouse->>JavaScript: pointermove 事件
JavaScript->>JavaScript: 計算:pos1=10, pos2=10
JavaScript->>Plant: 更新:left += 10px, top += 10px
Plant->>Plant: 在新位置渲染
User->>Mouse: 在 (120, 65) 釋放
Mouse->>JavaScript: pointerup 事件
JavaScript->>JavaScript: 移除監聽器
JavaScript->>JavaScript: 重置為下一次拖曳
移動計算說明:
- 測量 舊滑鼠位置與新滑鼠位置的差異
- 計算 應移動元素的距離
- 即時更新 元素的 CSS 位置屬性
- 儲存 新位置作為下一次移動計算基準
數學的視覺化表示
sequenceDiagram
participant Mouse
participant JavaScript
participant Plant
Mouse->>JavaScript: 從 (100,50) 移動到 (110,60)
JavaScript->>JavaScript: 計算:向右移動 10px,向下移動 10px
JavaScript->>Plant: 更新位置,向右 +10px,向下 +10px
Plant->>Plant: 在新位置渲染
stopElementDrag 函式:進行清理
在 elementDrag 函式結尾大括號後新增清理函式:
function stopElementDrag() {
// 移除文件層級的事件監聽器
document.onpointerup = null;
document.onpointermove = null;
}
為何清理很重要:
- 防止 因事件監聽器未清除而造成記憶體洩漏
- 停止 使用者放開植物時的拖曳行為
- 允許 其他元素可獨立進行拖曳
- 重設 系統為下一次拖曳操作做準備
不清理會發生什麼:
- 事件監聽器即使拖曳停止仍持續運行
- 隨著未使用的監聽器累積,效能降低
- 與其他元素互動時行為出錯
- 瀏覽器資源浪費於不必要的事件處理
理解 CSS 位置屬性
我們的拖曳系統操作兩個關鍵的 CSS 屬性:
| 屬性 | 控制內容 | 我們如何使用 |
|---|---|---|
top |
與頂部邊界的距離 | 拖曳垂直定位 |
left |
與左側邊界的距離 | 拖曳水平定位 |
關於 offset 屬性的重點:
offsetTop:相對於最近位置設定的父元素頂部的距離offsetLeft:相對於最近位置設定的父元素左側的距離- 定位上下文:這些值相對的參考是最近的有定位祖先元素
- 即時更新:修改 CSS 屬性時立刻改變
🎯 設計理念:此拖曳系統故意保持彈性——沒有“放置區域”或限制。使用者可以把植物放在任何位置,讓他們完整掌控植栽設計。
整合所有:您的完整拖曳系統
恭喜!您剛剛用純 JavaScript 建立了一個複雜的拖放系統。完整的 dragElement 函式現在包含一個強大的閉包,能管理:
您的閉包達成了什麼:
- 維持 每個植物獨立的私有位置變數
- 處理 從開始到結束的完整拖曳生命週期
- 提供 全螢幕範圍的平滑、靈敏移動
- 適當清理 資源避免記憶體洩漏
- 創造 直覺且具創意的生態箱設計介面
測試您的互動生態箱
現在測試您的互動生態箱吧!在瀏覽器打開 index.html,試試以下功能:
- 按住並點擊 任一植物開始拖曳
- 移動滑鼠或手指,觀察植物平滑跟隨移動
- 放開 放下植物於新的位置
- 嘗試 不同排列方式以探索介面
🥇 成就獎章:您已經使用專業開發者每日運用的核心概念,創造出一個完全互動的網頁應用。該拖放功能背後原理也被用於檔案上傳、看板系統與其他許多互動介面。
🔄 教學自我檢測
完整系統理解:驗證你對拖曳系統的掌握:
- ✅ 閉包如何維持每株植物的獨立狀態?
- ✅ 為何座標計算數學對流暢移動很重要?
- ✅ 如果忘記清理事件監聽器會怎樣?
- ✅ 此模式如何擴展到更複雜的互動?
程式碼品質反思:回顧您的完整解決方案:
- 模組化設計:每個植物擁有自己的閉包實例
- 事件效率:監聽器適當設定與清理
- 跨裝置支援:同時適用桌面與行動裝置
- 效能意識:避免記憶體洩漏和重複計算
GitHub Copilot Agent 挑戰 🚀
使用 Agent 模式完成以下挑戰:
描述: 為生態箱專案新增重置功能,將所有植物以平滑動畫帶回原始位置。
提示: 創建一個重置按鈕,點擊時使用 CSS 過渡效果,將所有植物從側邊欄的原始位置動畫地移回。函式需在頁面載入時儲存原始位置,按下重置時以一秒劃時間平滑移動。
欲了解更多,請參考 agent mode 。
🚀 額外挑戰:提升您的技能
準備將生態箱提升到新層級嗎?嘗試實作以下增強功能:
創意擴展:
- 雙擊 植物使其置頂(z-index 操作)
- 添加視覺回饋,例如滑鼠懸停時微光效果
- 實作邊界限制,防止植物被拖曳出生態箱外
- 建立儲存功能,用 localStorage 記錄植物位置
- 新增音效,在拾起和放下植物時播放
💡 學習機會:這些挑戰會教你新的 DOM 操控、事件處理與使用體驗設計技術。
課後測驗
複習與自學:深化理解
你已掌握 DOM 操控和閉包基礎,但學無止境!以下是擴展知識與技能的方向。
替代拖放方法
我們用 pointer 事件達最大彈性,但網頁開發還有多種選擇:
| 方法 | 適用情境 | 學習價值 |
|---|---|---|
| HTML 拖放 API | 檔案上傳、正式拖放區域 | 了解瀏覽器原生能力 |
| 觸控事件 | 行動專用互動 | 行動先行開發模式 |
CSS transform 屬性 |
平滑動畫 | 效能優化技術 |
進階 DOM 操控主題
學習下一步:
- 事件代理:高效管理多元素事件
- Intersection Observer:偵測元素出入視口
- Mutation Observer:監聽 DOM 結構變更
- Web Components:構建可重用封裝式 UI 元件
- 虛擬 DOM 概念:理解框架如何優化 DOM 更新
必備持續學習資源
技術文件:
- MDN Pointer Events 指南 - 全面 pointer 事件參考
- W3C Pointer Events 規範 - 官方標準文件
- JavaScript 閉包深入 - 進階閉包模式
瀏覽器相容性:
- CanIUse.com - 瀏覽器功能支援狀況
- MDN Browser Compatibility Data - 詳細相容性資料
練習機會:
- 製作 類似拖曳機制的拼圖遊戲
- 創建 支援拖放的看板任務管理
- 設計 可拖動照片排列的圖庫
- 嘗試 行動裝置觸控手勢操作
🎯 學習策略:最佳鞏固方式是多練習。嘗試建造不同變化的拖曳介面——每個專案都會教你更多用戶互動與 DOM 操控技巧。
⚡ 您可在接下來 5 分鐘內做些什麼
- 開啟瀏覽器開發者工具於主控台輸入
document.querySelector('body') - 嘗試用
innerHTML或textContent修改網頁文字 - 對任何按鈕或連結增加點擊事件監聽器
- 使用元素面板檢查 DOM 樹結構
🎯 這一小時您可以達成
- 完成課後小測驗並複習 DOM 操控概念
- 建立一個響應使用者點擊的互動網頁
- 練習各種事件類型的事件處理(click、mouseover、keypress)
- 打造簡易代辦清單或計數器應用
- 探索 HTML 元素與 JavaScript 物件關係
📅 您的 JavaScript 一週學習計畫
- 完成具拖放功能的互動生態箱專案
- 精通事件代理以提升事件處理效率
- 學習事件迴圈與非同步 JavaScript
- 練習閉包,建立帶有私有狀態的模組
- 探索最新 DOM API,如 Intersection Observer
- 不用框架建構互動元件
🌟 您的 JavaScript 一個月精通計畫
- 使用純 JavaScript 建置複雜單頁應用程式
- 學習並比較現代框架(React、Vue、Angular)與純 DOM 操控
- 參與 JavaScript 開源專案貢獻
- 精通高級概念如 Web Components 和自訂元素
- 建構效能優化的網頁應用
- 教授他人 DOM 操控與 JavaScript 基礎
🎯 您的 JavaScript DOM 精通時間軸
timeline
title DOM 與 JavaScript 學習進度
section 基礎 (15 分鐘)
DOM 理解: 元素選取方法
: 樹狀結構導覽
: 屬性存取模式
section 事件處理 (20 分鐘)
使用者互動: 指標事件基礎
: 事件監聽器設定
: 跨裝置相容性
: 事件阻止技巧
section 閉包 (25 分鐘)
範圍管理: 私有變數建立
: 函式持續存在
: 狀態管理模式
: 記憶體效率
section 拖曳系統 (30 分鐘)
互動功能: 座標追蹤
: 位置計算
: 移動數學
: 清理程序
section 進階模式 (45 分鐘)
專業技能: 事件委派
: 效能優化
: 錯誤處理
: 無障礙考量
section 框架理解 (1 週)
現代開發: 虛擬 DOM 概念
: 狀態管理函式庫
: 元件架構
: 建置工具整合
section 專家級 (1 個月)
進階 DOM API: 交叉觀察器
: 變異觀察器
: 自訂元素
: 網頁元件
🛠️ 您的 JavaScript 工具包總結
完成本課後,您已具備:
- DOM 精通:元素選取、屬性操作與樹狀結構導覽
- 事件專業:跨裝置指標事件處理
- 閉包理解:私有狀態管理與函式持續性
- 互動系統:完整拖放功能從零開始實作
- 效能意識:適當事件清理與記憶體管理
- 現代模式:職業開發中常見程式組織技術
- 用戶體驗:打造直覺、響應快速的介面
職業技能收穫:您已使用與以下同樣技術開發功能:
- Trello/看板系統:欄位間拖曳卡片
- 檔案上傳系統:拖放檔案處理
- 圖庫:照片排列介面
- 行動應用:觸控式互動模式
下一步:您已準備探索基於這些基礎 DOM 概念的現代框架如 React、Vue 或 Angular!
作業
免責聲明: 本文件係使用 AI 翻譯服務 Co-op Translator 所翻譯。雖然我們致力於確保翻譯的準確性,但請注意自動翻譯可能包含錯誤或不準確之處。原始文件的原文版本應被視為權威來源。對於重要資訊,建議採用專業人工翻譯。我們對於因使用本翻譯所導致的任何誤解或誤釋概不負責。


