以下是一個適合小團隊自用的 Chrome TodoList 插件開發示例,包含基礎功能(增刪改查、本地存儲、統計)和簡潔的交互設計。代碼結構清晰,適合新手學習或快速上手。
一、項目準備
創建插件項目目錄 todo-list-extension
,包含以下文件:
todo-list-extension/
├── manifest.json # 插件配置文件
├── popup.html # 彈出頁面
├── popup.css # 樣式文件
└── popup.js # 邏輯腳本
二、核心代碼實現
1. manifest.json
(插件配置)
{"manifest_version": 3,"name": "小團隊 TodoList","version": "1.0.0","description": "小團隊自用的任務管理工具,數據本地持久化","icons": {"16": "icon-16.png","48": "icon-48.png","128": "icon-128.png"},"action": {"default_popup": "popup.html","default_icon": {"16": "icon-16.png","48": "icon-48.png","128": "icon-128.png"}},"permissions": ["storage"], // 使用本地存儲需要此權限"content_security_policy": {"extension_pages": "script-src 'self'; object-src 'self'"}
}
說明:
manifest_version: 3
是 Chrome 推薦的最新版本,更安全高效。permissions: ["storage"]
用于訪問本地存儲(chrome.storage.local
)。- 需準備 16x16、48x48、128x128 的圖標(可臨時用占位圖)。
2. popup.html
(彈出頁面結構)
<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><link rel="stylesheet" href="popup.css">
</head>
<body><div class="container"><!-- 統計欄 --><div class="stats"><span>總任務:<span id="total">0</span></span><span>已完成:<span id="completed">0</span></span></div><!-- 添加任務表單 --><div class="add-task"><input type="text" id="taskInput" placeholder="輸入新任務(回車添加)"autocomplete="off"><button id="addBtn">添加</button></div><!-- 任務列表 --><ul id="taskList"></ul></div><script src="popup.js"></script>
</body>
</html>
3. popup.css
(樣式美化)
body {width: 350px;min-height: 400px;margin: 0;padding: 15px;font-family: 'Segoe UI', sans-serif;background: #f5f7fa;
}.container {max-width: 100%;
}.stats {color: #666;font-size: 12px;margin-bottom: 15px;display: flex;gap: 15px;
}.add-task {display: flex;gap: 8px;margin-bottom: 15px;
}#taskInput {flex: 1;padding: 8px 12px;border: 1px solid #ddd;border-radius: 4px;font-size: 14px;outline: none;
}#taskInput:focus {border-color: #4a90e2;box-shadow: 0 0 0 2px rgba(74, 144, 226, 0.1);
}#addBtn {padding: 8px 16px;background: #4a90e2;color: white;border: none;border-radius: 4px;cursor: pointer;font-size: 14px;transition: background 0.2s;
}#addBtn:hover {background: #357abd;
}#taskList {list-style: none;padding: 0;margin: 0;
}.task-item {display: flex;align-items: center;padding: 10px;background: white;border-radius: 4px;margin-bottom: 8px;box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);transition: transform 0.1s;
}.task-item:hover {transform: translateX(5px);
}.task-checkbox {width: 18px;height: 18px;margin-right: 12px;cursor: pointer;
}.task-content {flex: 1;font-size: 14px;color: #333;
}.task-content.completed {text-decoration: line-through;color: #999;
}.delete-btn {color: #ff4d4f;background: none;border: none;cursor: pointer;font-size: 16px;opacity: 0.7;transition: opacity 0.2s;
}.delete-btn:hover {opacity: 1;
}
4. popup.js
(核心邏輯)
// 初始化:加載本地存儲的任務
document.addEventListener('DOMContentLoaded', () => {loadTasks();renderTasks();
});// 獲取 DOM 元素
const taskInput = document.getElementById('taskInput');
const addBtn = document.getElementById('addBtn');
const taskList = document.getElementById('taskList');
const totalEl = document.getElementById('total');
const completedEl = document.getElementById('completed');// 添加任務(按鈕點擊或回車)
addBtn.addEventListener('click', addTask);
taskInput.addEventListener('keypress', (e) => {if (e.key === 'Enter') addTask();
});// 加載本地存儲的任務
function loadTasks() {chrome.storage.local.get(['tasks'], (result) => {const tasks = result.tasks || [];renderTasks(tasks);});
}// 渲染任務列表
function renderTasks(tasks = []) {// 清空舊列表taskList.innerHTML = '';// 統計數據const total = tasks.length;const completed = tasks.filter(t => t.completed).length;totalEl.textContent = total;completedEl.textContent = completed;// 渲染每個任務tasks.forEach(task => {const li = document.createElement('li');li.className = 'task-item';li.dataset.id = task.id; // 用 id 標識任務li.innerHTML = `<input type="checkbox" class="task-checkbox" ${task.completed ? 'checked' : ''}><span class="task-content ${task.completed ? 'completed' : ''}">${task.content}</span><button class="delete-btn">×</button>`;// 綁定復選框事件(標記完成/未完成)const checkbox = li.querySelector('.task-checkbox');checkbox.addEventListener('change', () => toggleTask(task.id));// 綁定刪除按鈕事件const deleteBtn = li.querySelector('.delete-btn');deleteBtn.addEventListener('click', () => deleteTask(task.id));taskList.appendChild(li);});
}// 添加新任務
function addTask() {const content = taskInput.value.trim();if (!content) return; // 空任務不添加const newTask = {id: Date.now(), // 用時間戳作為唯一 idcontent,completed: false,createdAt: new Date().toISOString()};// 讀取現有任務并追加新任務chrome.storage.local.get(['tasks'], (result) => {const tasks = result.tasks || [];tasks.push(newTask);saveTasks(tasks); // 保存到本地存儲taskInput.value = ''; // 清空輸入框});
}// 切換任務完成狀態
function toggleTask(taskId) {chrome.storage.local.get(['tasks'], (result) => {const tasks = result.tasks || [];const index = tasks.findIndex(t => t.id === taskId);if (index !== -1) {tasks[index].completed = !tasks[index].completed;saveTasks(tasks);}});
}// 刪除任務
function deleteTask(taskId) {chrome.storage.local.get(['tasks'], (result) => {const tasks = result.tasks || [];const filtered = tasks.filter(t => t.id !== taskId);saveTasks(filtered);});
}// 保存任務到本地存儲
function saveTasks(tasks) {chrome.storage.local.set({ tasks }, () => {renderTasks(tasks); // 保存后重新渲染});
}
三、測試與使用
- 準備圖標:臨時找 3 個尺寸的圖標(或用在線工具生成),命名為
icon-16.png
、icon-48.png
、icon-128.png
放入項目目錄。 - 加載插件:
- 打開 Chrome 瀏覽器,進入
chrome://extensions
。 - 開啟右上角「開發者模式」→ 點擊「加載已解壓的擴展程序」→ 選擇項目目錄
todo-list-extension
。
- 打開 Chrome 瀏覽器,進入
- 使用插件:
- 點擊瀏覽器右上角的插件圖標,彈出 TodoList 界面。
- 輸入任務內容,點擊「添加」或按回車鍵添加任務。
- 勾選復選框標記任務完成(文字會劃線),點擊「×」刪除任務。
- 關閉插件后重新打開,數據會保留(本地存儲)。
四、擴展方向(小團隊可能需要)
- 任務分類/標簽:添加「工作」「生活」等標簽,按分類篩選任務。
- 截止日期提醒:為任務添加截止時間,到期前彈出通知(需
alarms
權限)。 - 團隊共享:結合團隊協作工具(如飛書、Trello API)同步任務(需后端服務)。
- 數據備份:添加「導出/導入」功能,支持 JSON 文件備份(用
chrome.downloads
API)。
這個示例實現了小團隊最核心的任務管理需求,代碼簡潔易擴展,適合作為團隊內部工具快速落地。