跳至主要内容

3 篇文章 含有標籤「版本控制」

檢視所有標籤

事件物件屬性 e.target 與 e.currentTarget 的差異與應用 | 學習筆記

· 閱讀時間約 4 分鐘
KD Chang
Builder, Curator & Lifelong Learner

前言​

在網頁開發中,事件處理是前端工程師必須熟悉的基礎知識之一。當我們使用 JavaScript 或框架(如 Vue、React)監聽 DOM 事件時,瀏覽器會提供一個事件物件(event object)給監聽函式,透過它我們能取得觸發事件的相關資訊。而在事件物件中,最常被初學者混淆的兩個屬性就是 e.target 與 e.currentTarget。

這兩者的差別看似微小,但實際上與事件冒泡機制息息相關。如果理解不清,會導致點擊判斷錯誤、事件綁定邏輯混亂,甚至出現無法預期的行為。本文將從概念、重點摘要,再到程式碼範例,逐步說明 e.target 與 e.currentTarget 的異同,並介紹實際開發中如何正確使用。


重點摘要​

  1. 事件冒泡(Event Bubbling)

    • 當某個元素觸發事件時,事件會從最深層的子元素向外層父元素依序傳遞。
    • 這意味著外層元素的事件監聽器也可能被觸發。
  2. e.target

    • 代表「事件最初發生的元素」。
    • 使用者實際點擊或操作的 DOM 元素,不論事件是否冒泡到其他父層。
  3. e.currentTarget

    • 代表「當前正在處理事件的元素」。
    • 永遠指向事件監聽器綁定的元素。
  4. 差異核心

    • e.target = 使用者操作的來源元素。
    • e.currentTarget = 當前呼叫事件處理函式的元素。
  5. 常見用途

    • e.target:用於判斷使用者點擊了哪個子元素,常用於事件代理(event delegation)。
    • e.currentTarget:用於保證取得事件綁定的元素本身,避免因冒泡導致判斷錯誤。

範例一:基本點擊事件​

以下是一個簡單的 HTML 結構:

<div id="outer" style="padding:20px; background:lightgray;">
Outer Div
<button id="inner">Click Me</button>
</div>

<script>
const outer = document.getElementById('outer');

outer.addEventListener('click', (e) => {
console.log('target:', e.target.id);
console.log('currentTarget:', e.currentTarget.id);
});
</script>

執行結果​

  1. 點擊按鈕(id="inner"):

    • e.target.id → inner
    • e.currentTarget.id → outer
  2. 點擊外層灰色區塊(id="outer"):

    • e.target.id → outer
    • e.currentTarget.id → outer

說明​

  • 使用者實際點擊按鈕,所以 e.target 是 inner。
  • 但因為事件冒泡,outer 的監聽器被觸發,因此 e.currentTarget 永遠是 outer。
  • 這正好展示了兩者的不同:一個描述事件來源,一個描述處理者。

範例二:事件代理(Event Delegation)​

事件代理是一種常見技巧,將監聽器掛在父層元素,由它統一處理子元素的事件。這種情境下,e.target 就非常重要。

<ul id="list">
<li data-id="1">Item 1</li>
<li data-id="2">Item 2</li>
<li data-id="3">Item 3</li>
</ul>

<script>
const list = document.getElementById('list');

list.addEventListener('click', (e) => {
console.log('target tag:', e.target.tagName);
console.log('currentTarget tag:', e.currentTarget.tagName);

if (e.target.tagName === 'LI') {
console.log('You clicked item with data-id:', e.target.dataset.id);
}
});
</script>

執行結果​

  • 點擊 Item 2 時:

    • e.target.tagName → LI
    • e.currentTarget.tagName → UL
    • 印出 "You clicked item with data-id: 2"

說明​

  • list(UL)負責監聽整個清單,這就是 e.currentTarget。
  • 實際點擊的 <li> 元素才是 e.target。
  • 藉由 e.target,我們能知道使用者點的是哪個清單項目,而不用對每個 <li> 綁定監聽器。

範例三:模擬 Vue 的 .self 行為​

在 Vue 中有一個 .self 修飾符,代表「只有點擊元素本身,而不是子元素時,事件才觸發」。這其實就是透過 e.target === e.currentTarget 判斷。

<div id="modal" style="width:300px; height:200px; background:rgba(0,0,0,0.5);">
<div style="width:100px; height:100px; background:white; margin:50px auto;"></div>
</div>

<script>
const modal = document.getElementById('modal');

modal.addEventListener('click', (e) => {
if (e.target === e.currentTarget) {
console.log('Clicked on modal background, close modal');
} else {
console.log('Clicked on inner content, do nothing');
}
});
</script>

說明​

  • 點擊外層灰色背景時:e.target === e.currentTarget → 成立 → 關閉彈窗。
  • 點擊白色內層時:e.target 為內層 div,而 e.currentTarget 為外層 → 不相等 → 不關閉。

這個邏輯就是框架中 .self 修飾符的實作原理。


總結​

  • e.target 與 e.currentTarget 都是事件物件的重要屬性。
  • e.target 表示事件來源,是使用者實際操作的元素。
  • e.currentTarget 表示事件處理者,是目前綁定監聽器的元素。
  • 理解這兩者的差別,對於處理事件冒泡、事件代理、以及控制複雜 UI 行為都至關重要。

當我們需要知道「使用者點了哪個子元素」時,請使用 e.target。當我們需要確保「正在處理事件的元素本身」時,請使用 e.currentTarget。

掌握這個觀念,能讓我們在撰寫事件監聽邏輯時更精準,避免誤判來源,也能設計出更乾淨與可維護的程式碼。

Git 指令學習筆記 | 學習筆記

· 閱讀時間約 6 分鐘
KD Chang
Builder, Curator & Lifelong Learner

Git 是現代軟體開發中最常使用的分散式版本控制系統,它幫助開發者管理源代碼的版本和協作。這篇教學將從基礎開始,介紹 Git 的常用命令並提供實際範例,幫助你熟悉如何使用 Git 來進行版本控制與協作。

1. 初始化 Git 倉庫 (git init)​

在專案資料夾中使用 git init 可以初始化一個新的 Git 倉庫,這樣就可以開始使用 Git 來管理專案中的檔案版本。

git init

執行後會在專案資料夾內建立一個 .git 的隱藏資料夾,這表示這個資料夾已經被 Git 所管理。

2. 查看當前狀態 (git status)​

在進行版本控制時,使用 git status 可以查看專案的當前狀態。這個命令會顯示哪些檔案已經被修改、哪些檔案尚未加入版本控制。

git status

這會列出所有變更過的檔案(包括已修改、尚未追蹤的檔案等)以及當前分支的狀態。

3. 新增檔案到暫存區 (git add)​

修改檔案後,必須先使用 git add 把檔案新增到暫存區,才可以進行提交。使用 git add 可以指定單一檔案或多個檔案,或者一次將所有檔案加入暫存區。

git add filename.txt

或將所有變更加入暫存區:

git add .

4. 提交變更 (git commit)​

將檔案從暫存區提交到本地版本庫使用 git commit。每次提交時,需要提供一個簡短的描述,解釋這次提交的內容。

git commit -m "新增使用者登錄功能"

5. 設定 Git 使用者資訊 (git config)​

在進行提交之前,必須設定 Git 的使用者名稱和電子郵件。這些資料會與每次提交關聯。

git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"

這會把你的名稱和郵箱寫入全域設定,未來每次提交都會使用這些設定。

6. 查看提交歷史 (git log)​

使用 git log 可以查看專案的提交歷史。這會顯示每次提交的詳細信息,包括提交哈希值、作者、日期和提交訊息。

git log

如果希望更簡潔的輸出,可以使用 --oneline 參數:

git log --oneline

7. 恢復檔案 (git restore)​

如果你修改了一些檔案並且還沒有提交,可以使用 git restore 恢復檔案到上次提交的狀態,撤銷變更。

git restore filename.txt

如果想撤銷暫存區的變更,可以使用:

git restore --staged filename.txt

8. 追蹤檔案變動紀錄 (git blame)​

如果你想查看某個檔案每一行是誰在什麼時候修改的,可以使用 git blame。

git blame filename.txt

這會顯示每一行的修改者與修改時間,有助於了解程式碼的歷史。

9. 建立分支 (git branch)​

在 Git 中,分支讓你能夠並行地進行多個工作。你可以使用 git branch 查看目前所有的分支。

git branch

要創建新的分支:

git branch feature-login

10. 切換分支 (git switch)​

要切換到不同的分支,可以使用 git switch。例如,切換到 feature-login 分支:

git switch feature-login

如果你要創建並切換到一個新的分支,可以加上 -c 選項:

git switch -c feature-register

11. 切換提交紀錄或分支 (git checkout)​

雖然 git switch 是較新的命令,但仍然可以使用 git checkout 切換分支或還原檔案。要切換到某個分支:

git checkout feature-login

若要還原某個檔案到指定的提交:

git checkout <commit_hash> filename.txt

12. 合併分支 (git merge)​

將不同分支的更改合併回主分支可以使用 git merge。首先切換到目標分支(例如 main),然後執行合併操作:

git switch main
git merge feature-login

如果有衝突,Git 會提示你解決衝突。

13. 重新整理提交歷史 (git rebase)​

git rebase 用來重新整理提交歷史,將一個分支的更改重新應用到另一個分支上,使歷史更為線性。

git switch feature-login
git rebase main

這會將 feature-login 分支的變更,重新應用到 main 分支的最新提交上。

14. 重置提交 (git reset)​

如果你想取消最近一次的提交,可以使用 git reset。使用 --soft 保留檔案變更,--hard 則會刪除變更:

git reset --soft HEAD^

這會將上一個提交撤回,但保留檔案變更;若使用 --hard,則會完全撤回提交及變更。

15. 查看操作紀錄 (git reflog)​

git reflog 可以幫助你查看 HEAD 的操作紀錄,即便你進行了 reset 或 checkout 等操作。

git reflog

這個命令列出所有曾經指向 HEAD 的 commit 參考,並且可以用來恢復丟失的提交。

16. 暫存變更 (git stash)​

如果你正在進行某些變更,但又需要切換到其他分支處理緊急問題,可以使用 git stash 暫時儲存未提交的變更:

git stash

這會暫時保存變更,並恢復工作目錄到最後一次提交的狀態。待你完成緊急工作後,可以使用 git stash pop 恢復變更。

17. 選擇性地應用提交 (git cherry-pick)​

git cherry-pick 讓你可以選擇性地將某個提交應用到當前分支。例如,將 feature-login 分支的某個提交應用到 main 分支:

git cherry-pick <commit_hash>

這對於選擇性地將某些特定變更移動到其他分支非常有用。

18. 子模組 (git submodule)​

當專案中有其他專案作為依賴時,可以使用 Git 子模組來管理。首先,將子模組加入專案:

git submodule add <repository_url> path/to/submodule

這會在專案中加入一個指向其他 Git 倉庫的子模組。在克隆專案時,記得加上 --recurse-submodules 來獲取子模組的內容。


總結

以上介紹了 Git 中一些常用的命令,這些命令幾乎涵蓋了日常開發中的大部分需求。熟練掌握 Git 讓你在開發過程中更加高效,無論是單人開發還是團隊協作,都能大大提高工作流的順暢性。如果你還有進一步的需求或疑問,隨時可以深入學習 Git 的進階技巧。

Git 入門教學筆記:從零開始學版本控制 | 學習筆記

· 閱讀時間約 4 分鐘
KD Chang
Builder, Curator & Lifelong Learner

為什麼要學 Git?​

在軟體開發中,版本控制是一個不可或缺的工具。Git 是目前最流行的版本控制系統,它能幫助你:

  • 記錄每次修改的歷史紀錄
  • 回復到任一個過去的狀態
  • 多人協作開發不衝突
  • 管理分支進行實驗性開發

無論是獨立開發者、團隊協作,還是參與開源專案,Git 都是你的好夥伴。


一、安裝 Git​

macOS​

brew install git

Ubuntu / Debian​

sudo apt update
sudo apt install git

Windows​

請至官網下載安裝:https://git-scm.com


二、基本設定​

第一次使用 Git 前,請先設定你的名稱與 Email(這會記錄在每次提交的資訊中):

git config --global user.name "你的名字"
git config --global user.email "you@example.com"

你也可以檢查目前的設定:

git config --list

三、建立本地倉庫(repository)​

建立一個新資料夾並初始化 Git​

mkdir my-project
cd my-project
git init

此時 .git/ 目錄會被建立,代表你已經在這個資料夾啟用了版本控制。


四、版本控制的基本流程​

Git 的工作流程大致分為三個區域:

  1. 工作區(Working Directory):你實際修改的檔案
  2. 暫存區(Staging Area):準備提交的檔案
  3. 版本庫(Repository):正式提交的版本歷史

1. 查看狀態​

git status

2. 將檔案加入暫存區​

git add 檔名
# 或加入全部變動檔案
git add .

3. 提交版本(commit)​

git commit -m "加入了首頁 HTML 結構"

五、版本紀錄與回溯​

查看提交紀錄​

git log

如果想要簡潔查看

git log --oneline

回到先前的狀態(例如最近一次提交)​

git checkout HEAD^
# 回到上上一個版本
git checkout HEAD~2

但請注意這樣會進入「detached HEAD」狀態,只是暫時查看,不適合繼續開發。


六、分支操作(branch)​

分支是 Git 強大的一環,可以讓你同時開發多個功能而互不干擾。

建立新分支​

git branch feature-login

切換分支​

git checkout feature-login

或合併成一行:

git checkout -b feature-login

合併分支​

切回主分支(通常是 main 或 master):

git checkout main
git merge feature-login

七、遠端倉庫(Remote Repository)​

若你使用 GitHub、GitLab 等服務,可以將本地專案推送到遠端:

新增遠端倉庫​

git remote add origin https://github.com/yourname/yourproject.git

推送本地分支​

git push -u origin main

拉取遠端最新變更​

git pull origin main

八、.gitignore 檔案​

.gitignore 用來指定不想被 Git 管理的檔案,例如:

node_modules/
.env
*.log
.DS_Store

建立一個 .gitignore 檔案,放進你專案根目錄,就能避免把不該版本控制的東西送到遠端倉庫。


九、常見狀況與解法​

修改後不小心沒 add 就 commit 了?​

可用下列方式補上:

git add 新增的檔案
git commit --amend

想撤銷修改?​

還沒 add 的:

git checkout -- 檔案名

已經 add 了但還沒 commit:

git reset HEAD 檔案名

十、總結:從習慣開始,讓版本控制變簡單​

熟悉 Git 的過程一開始可能會覺得繁瑣,但當你習慣了之後,它會成為你每天工作中不可或缺的工具。建議你在小專案中練習基本指令,隨手記錄每次的變更,透過良好的 commit message,讓未來的你感謝現在有好好整理的你。

如果你希望與他人協作開發,Git 更能大幅簡化流程、避免衝突。下一步,你可以學習 Pull Request(PR)、Git Flow、Rebase 等進階技巧,逐步精進你的版本控制能力。

參考文件

  1. Conventional Commits
  2. 約定式提交
  3. [Git] Conventional Commits 規範性提交
  4. git reflog - 還原大招
  5. 為你自己學 Git