一个typecho的todolist自定义页面
这就是一个千问给我写的todolist页面虽然我原本要的是一个html
不过这个php也不是没有用处
代码在下面了
<?php
/**
* Todo List
* @package custom
*/
if (!defined('__TYPECHO_ROOT_DIR__')) exit;
$this->need('header.php');
?>
<style>
.todo-container { max-width: 600px; margin: 40px auto; padding: 0 20px; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; }
.todo-header { display: flex; gap: 10px; margin-bottom: 30px; }
.todo-input { flex: 1; padding: 12px 16px; border: 2px solid #e0e0e0; border-radius: 8px; font-size: 16px; outline: none; transition: border-color 0.2s; background: var(--bg-color, #fff); color: var(--text-color, #333); }
.todo-input:focus { border-color: #4a90d9; }
.todo-add-btn { padding: 12px 24px; background: #4a90d9; color: #fff; border: none; border-radius: 8px; font-size: 16px; cursor: pointer; transition: background 0.2s; }
.todo-add-btn:hover { background: #357abd; }
.todo-list { list-style: none; padding: 0; margin: 0; }
.todo-item { display: flex; align-items: center; gap: 12px; padding: 14px 16px; margin-bottom: 8px; background: var(--item-bg, #f9f9f9); border-radius: 8px; transition: all 0.2s; animation: slideIn 0.3s ease; }
.todo-item:hover { transform: translateX(4px); }
.todo-item.completed .todo-text { text-decoration: line-through; opacity: 0.5; }
.todo-checkbox { width: 20px; height: 20px; cursor: pointer; accent-color: #4a90d9; flex-shrink: 0; }
.todo-text { flex: 1; font-size: 15px; word-break: break-word; color: var(--text-color, #333); }
.todo-delete { opacity: 0; background: none; border: none; color: #e74c3c; font-size: 18px; cursor: pointer; padding: 4px 8px; border-radius: 4px; transition: opacity 0.2s; }
.todo-item:hover .todo-delete { opacity: 1; }
.todo-delete:hover { background: rgba(231,76,60,0.1); }
.todo-stats { text-align: center; margin-top: 20px; font-size: 13px; opacity: 0.6; color: var(--text-color, #333); }
.todo-empty { text-align: center; padding: 40px; opacity: 0.4; font-size: 14px; color: var(--text-color, #333); }
@keyframes slideIn { from { opacity: 0; transform: translateY(-10px); } to { opacity: 1; transform: translateY(0); } }
/* 暗色模式自动适配 */
@media (prefers-color-scheme: dark) {
:root { --bg-color: #1a1a2e; --text-color: #e0e0e0; --item-bg: #16213e; }
.todo-input { border-color: #333; }
}
</style>
<div class="todo-container">
<div class="todo-header">
<input type="text" class="todo-input" id="todoInput" placeholder="添加新的待办事项..." autofocus>
<button class="todo-add-btn" id="addBtn">添加</button>
</div>
<ul class="todo-list" id="todoList"></ul>
<div class="todo-stats" id="todoStats"></div>
</div>
<script>
(function() {
const STORAGE_KEY = 'typecho_todo_list';
const input = document.getElementById('todoInput');
const addBtn = document.getElementById('addBtn');
const listEl = document.getElementById('todoList');
const statsEl = document.getElementById('todoStats');
let todos = JSON.parse(localStorage.getItem(STORAGE_KEY) || '[]');
function save() { localStorage.setItem(STORAGE_KEY, JSON.stringify(todos)); }
function render() {
listEl.innerHTML = '';
if (todos.length === 0) {
listEl.innerHTML = '<li class="todo-empty">暂无待办事项,享受当下吧 ✨</li>';
statsEl.textContent = '';
return;
}
todos.forEach((todo, index) => {
const li = document.createElement('li');
li.className = 'todo-item' + (todo.done ? ' completed' : '');
li.innerHTML = `
<input type="checkbox" class="todo-checkbox" ${todo.done ? 'checked' : ''}>
<span class="todo-text">${escapeHtml(todo.text)}</span>
<button class="todo-delete" title="删除">×</button>
`;
li.querySelector('.todo-checkbox').addEventListener('change', () => toggle(index));
li.querySelector('.todo-delete').addEventListener('click', () => remove(index));
listEl.appendChild(li);
});
const done = todos.filter(t => t.done).length;
statsEl.textContent = `${done} / ${todos.length} 已完成`;
}
function add() {
const text = input.value.trim();
if (!text) return;
todos.unshift({ text, done: false, createdAt: Date.now() });
input.value = '';
save(); render();
}
function toggle(index) { todos[index].done = !todos[index].done; save(); render(); }
function remove(index) { todos.splice(index, 1); save(); render(); }
function escapeHtml(str) { const d = document.createElement('div'); d.textContent = str; return d.innerHTML; }
addBtn.addEventListener('click', add);
input.addEventListener('keydown', e => { if (e.key === 'Enter') add(); });
render();
})();
</script>
<?php $this->need('footer.php'); ?>