iT邦幫忙

2025 iThome 鐵人賽

DAY 23
0
佛心分享-IT 人自學之術

30 天體驗:從程式菜鳥到前端新手工程師系列 第 23

進化你的網頁-讓清單真的「動起來」!(Day23)

  • 分享至 

  • xImage
  •  

到目前為止,我們已經用 HTML + CSS 做出一個 待辦清單(To-Do List) 的外觀。
今天要進入最有趣的部分:
讓清單真的可以「互動」🎯

今日目標
完成三大功能:
1️⃣ 新增任務
2️⃣ 刪除任務
3️⃣ 標記任務完成狀態

第一步:建立基本 HTML 結構

<div class="todo-container">
  <h2>📋 我的待辦清單</h2>

  <div class="input-area"> //新增的class
    <input type="text" id="taskInput" placeholder="請輸入任務..." />
    <button id="addBtn">新增</button>
  </div>

  <ul id="taskList"></ul>
</div>

說明:
< input > 是讓使用者輸入文字。
< button > 是按下去觸發「新增任務」的動作。
< ul > 是放任務的清單,每新增一個任務就會在這裡多一個 < li >。

第二步:加上簡單的 CSS 美化
我們先讓畫面好看一點,也方便觀察互動變化。

.todo-container {
  width: 300px;
  margin: 60px auto;
  background: #fff;
  border-radius: 12px;
  padding: 20px;
  box-shadow: 0 4px 12px rgba(0,0,0,0.1);
}

.input-area {
  display: flex;
  gap: 10px;
}

input {
  flex: 1;
  padding: 8px;
  border: 1px solid #ccc;
  border-radius: 8px;
}

button {
  padding: 8px 12px;
  background-color: #5c9ded;
  border: none;
  color: white;
  border-radius: 8px;
  cursor: pointer;
}

button:hover {
  background-color: #3b7cd4;
}

ul {
  list-style: none;
  padding: 0;
  margin-top: 20px;
}

li {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 8px;
  border-bottom: 1px solid #eee;
}

li.completed span {
  text-decoration: line-through;
  color: gray;
}

.deleteBtn {
  background: transparent;
  border: none;
  color: red;
  cursor: pointer;
}

這樣就會有一個乾淨的小卡片樣式,每個任務會有「文字」和「刪除」按鈕。
https://ithelp.ithome.com.tw/upload/images/20251011/20178705NgcrzAeOaj.png

第三步:用 JavaScript 加上互動功能
這是今天的主角!
我們要讓三個功能實現:

1️⃣ 新增任務

當使用者輸入任務文字後按下「新增」,要讓畫面多出一個新的 < li >。

const addBtn = document.getElementById('addBtn');
const taskInput = document.getElementById('taskInput');
const taskList = document.getElementById('taskList');

// 按下新增按鈕後觸發
addBtn.addEventListener('click', () => {
  const taskText = taskInput.value.trim(); // 取出輸入框內容
  if (taskText === '') {
    alert('請輸入任務內容!');
    return;
  }

  // 建立一個新的 li 元素
  const li = document.createElement('li');
  li.innerHTML = `
    <span>${taskText}</span>
    <button class="deleteBtn">刪除</button>
  `;

  taskList.appendChild(li); // 加到清單裡
  taskInput.value = ''; // 清空輸入框
});

🔍 重點說明:

taskInput.value 取得輸入的文字內容。
.trim() 是去掉多餘空白,避免只輸入空格。
document.createElement('li') 建立一個新的清單項目。
.innerHTML 讓我們可以直接在 li 裡放入 HTML。
.appendChild() 把這個 li 加進 < ul > 裡。

https://ithelp.ithome.com.tw/upload/images/20251011/20178705DAMNKnx9p7.png

2️⃣ 標記任務完成(打勾效果)

這部分我們希望「點任務文字」就能切換完成狀態。

taskList.addEventListener('click', (e) => {
  if (e.target.tagName === 'SPAN') {
    e.target.parentElement.classList.toggle('completed');
  }
});

💡 這段的邏輯:
e.target 代表被點擊的元素。
如果點到的是 < span >(任務文字那塊),
就幫它的父層 < li > 加上或移除 .completed。
.completed 是我們在 CSS 設定的「劃掉文字」樣式。

https://ithelp.ithome.com.tw/upload/images/20251011/20178705tb3bFcVYfY.png

3️⃣ 刪除任務

我們在新增任務時有加上刪除按鈕,
現在就讓那個按鈕真的能刪掉任務!

taskList.addEventListener('click', (e) => {
  if (e.target.classList.contains('deleteBtn')) {
    e.target.parentElement.remove();
  }
});

💡 classList.contains('deleteBtn') 用來判斷點到的是否是刪除按鈕。
若是,就用 .remove() 把整個 < li > 移除。

https://ithelp.ithome.com.tw/upload/images/20251011/20178705UH4KIknJTQ.pnghttps://ithelp.ithome.com.tw/upload/images/20251011/20178705IsBYwwariq.png

🧩 最終整合程式碼

<div class="todo-container">
  <h2>我的待辦清單</h2>
  <div class="input-area">
    <input type="text" id="taskInput" placeholder="請輸入任務..." />
    <button id="addBtn">新增</button>
  </div>
  <ul id="taskList"></ul>
</div>

<script>
  const addBtn = document.getElementById('addBtn');
  const taskInput = document.getElementById('taskInput');
  const taskList = document.getElementById('taskList');

  addBtn.addEventListener('click', () => {
    const taskText = taskInput.value.trim();
    if (taskText === '') {
      alert('請輸入任務內容!');
      return;
    }

    const li = document.createElement('li');
    li.innerHTML = `
      <span>${taskText}</span>
      <button class="deleteBtn">刪除</button>
    `;
    taskList.appendChild(li);
    taskInput.value = '';
  });

  taskList.addEventListener('click', (e) => {
    if (e.target.tagName === 'SPAN') {
      e.target.parentElement.classList.toggle('completed');
    } else if (e.target.classList.contains('deleteBtn')) {
      e.target.parentElement.remove();
    }
  });
</script>

🎉 今天的成果
✅ 可以新增任務
✅ 可以點擊任務打勾完成
✅ 可以刪除任務

你已經正式做出一個「真正會動的前端小作品」🎉
這就是最基本的 JavaScript 應用範例!

🌱 明日預告
明天我們要繼續讓這份清單更強大!
✨ 讓使用者按「Enter」也能新增任務
💾 學習使用 localStorage,把清單資料「存起來」!


上一篇
整合起來吧!小專案開跑 (Day22)
下一篇
讓清單「更聰明」— 加入 Enter 快捷鍵 + localStorage 資料儲存 (Day24)
系列文
30 天體驗:從程式菜鳥到前端新手工程師30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言