效果預覽:https://sevlt.github.io/to-do-list-mobile-terminal/index.html
Html 代碼:
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Todo</title> <link rel="stylesheet" href="./css/reset.min.css" /> <link rel="stylesheet" href="./css/style.css" /> </head> <body> <header> <input type="text" placeholder="輸入待辦事項..." id="item" /> <button id="add"> <!-- 添加按鈕 SVG --> <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 16 16" style="enable-background: new 0 0 16 16;" xml:space="preserve" > <g> <path class="fill" d="M16,8c0,0.5-0.5,1-1,1H9v6c0,0.5-0.5,1-1,1s-1-0.5-1-1V9H1C0.5,9,0,8.5,0,8s0.5-1,1-1h6V1c0-0.5,0.5-1,1-1s1,0.5,1,1v6h6C15.5,7,16,7.5,16,8z" /> </g> </svg> </button> </header> <div class="container"> <!-- 未完成事項 --> <ul class="todo" id="not"></ul> <!-- 已完成事項 --> <ul class="todo" id="done"></ul> </div> <script src="./js/main.js"></script> </body> </html>
CSS 代碼:
body { background-color: #edf0f1; padding: 70px 0 0 0; } /* 按鈕 SVG 背景爲透明 */ .noFill { fill: none; } header { width: 100%; height: 70px; position: fixed; padding: 12px; top: 0; left: 0; z-index: 1; background-color: #27b99a; box-shadow: 0px 2px 4px rgba(44, 62, 80, 0.75); border-bottom-left-radius: 10px; border-bottom-right-radius: 10px; } header input { width: 100%; height: 46px; color: #fff; font-size: 15px; font-weight: 400; text-indent: 18px; background-color: rgba(255, 255, 255, 0.2); border-top-left-radius: 5px; border-bottom-left-radius: 5px; border-top-right-radius: 23px; border-bottom-right-radius: 23px; border: 0; outline: none; } /* 佔位符顏色 */ header input::-webkit-input-placeholder { color: rgba(255, 255, 255, 0.75); } header button { position: absolute; width: 46px; height: 46px; top: 12px; right: 12px; border-radius: 50%; border: 0; background-color: #fff; cursor: pointer; outline: none; } header button svg { position: absolute; width: 16px; height: 16px; top: 0; bottom: 0; left: 0; right: 0; margin: auto; } /* 按鈕 SVG 顏色 */ header button svg .fill { fill: #27b99a; } .container { width: 100%; padding: 14px 14px 0 14px; } ul.todo { width: 100%; } ul.todo li { width: 100%; min-height: 50px; font-size: 14px; font-weight: 500; color: #444; line-height: 22px; background-color: #fff; border-radius: 5px; box-shadow: 0px 1px 2px rgba(44, 62, 80, 0.1); padding: 14px 0 0 14px; margin: 0 0 10px 0; position: relative; } ul.todo li:last-child { margin: 0; } ul.todo li .buttons { position: absolute; width: 100px; height: 50px; top: 0; right: 0; } ul.todo li .buttons button { position: relative; width: 50px; height: 50px; float: left; background: none; border: 0; box-shadow: none; cursor: pointer; outline: none; } /* 刪除和完成兩個按鈕之間的分隔線 */ ul.todo li .buttons button:last-child:before { content: ''; position: absolute; width: 1px; height: 30px; top: 10px; left: 0; background-color: #edf0f1; } ul.todo li .buttons button svg { position: absolute; width: 22px; height: 22px; top: 0; bottom: 0; left: 0; right: 0; margin: auto; } ul.todo li .buttons button.remove svg .fill { fill: #e8d4d0; transition: fill 0.2s; } ul.todo li .buttons button.remove svg:hover .fill { fill: #ed7675; } ul.todo li .buttons button.complete svg .fill { fill: #27b99a; } ul.todo li .buttons button.complete svg { border-radius: 11px; border: 1px solid #27b99a; } ul.todo#not li .buttons button.complete svg:hover { background: #27b99a; } ul.todo#not li .buttons button.complete svg:hover .fill { fill: #fff; } ul.todo#done li .buttons button.complete svg { background: #27b99a; } ul.todo#done li .buttons button.complete svg .fill { fill: #fff; } /* 若 ul 非空,則第一個子元素上邊距爲 50px */ ul.todo#done:not(:empty) { padding: 50px 0 0 0; } /* 未完成事項與已完成事項的分隔線 */ ul.todo#done li:first-child:before { content: ''; position: absolute; top: -25px; width: 136px; height: 1px; background: #e6edeb; left: 0; right: 0; margin: auto; }
JavaScript 代碼:
var removeSVG = '<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 22 22" style="enable-background:new 0 0 22 22;" xml:space="preserve"><rect class="noFill" width="22" height="22"/><g><g><path class="fill" d="M16.1,3.6h-1.9V3.3c0-1.3-1-2.3-2.3-2.3h-1.7C8.9,1,7.8,2,7.8,3.3v0.2H5.9c-1.3,0-2.3,1-2.3,2.3v1.3c0,0.5,0.4,0.9,0.9,1v10.5c0,1.3,1,2.3,2.3,2.3h8.5c1.3,0,2.3-1,2.3-2.3V8.2c0.5-0.1,0.9-0.5,0.9-1V5.9C18.4,4.6,17.4,3.6,16.1,3.6z M9.1,3.3c0-0.6,0.5-1.1,1.1-1.1h1.7c0.6,0,1.1,0.5,1.1,1.1v0.2H9.1V3.3z M16.3,18.7c0,0.6-0.5,1.1-1.1,1.1H6.7c-0.6,0-1.1-0.5-1.1-1.1V8.2h10.6V18.7z M17.2,7H4.8V5.9c0-0.6,0.5-1.1,1.1-1.1h10.2c0.6,0,1.1,0.5,1.1,1.1V7z"/></g><g><g><path class="fill" d="M11,18c-0.4,0-0.6-0.3-0.6-0.6v-6.8c0-0.4,0.3-0.6,0.6-0.6s0.6,0.3,0.6,0.6v6.8C11.6,17.7,11.4,18,11,18z"/></g><g><path class="fill" d="M8,18c-0.4,0-0.6-0.3-0.6-0.6v-6.8c0-0.4,0.3-0.6,0.6-0.6c0.4,0,0.6,0.3,0.6,0.6v6.8C8.7,17.7,8.4,18,8,18z"/></g><g><path class="fill" d="M14,18c-0.4,0-0.6-0.3-0.6-0.6v-6.8c0-0.4,0.3-0.6,0.6-0.6c0.4,0,0.6,0.3,0.6,0.6v6.8C14.6,17.7,14.3,18,14,18z"/></g></g></g></svg>' var completeSVG = '<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 22 22" style="enable-background:new 0 0 22 22;" xml:space="preserve"><rect y="0" class="noFill" width="22" height="22"/><g><path class="fill" d="M9.7,14.4L9.7,14.4c-0.2,0-0.4-0.1-0.5-0.2l-2.7-2.7c-0.3-0.3-0.3-0.8,0-1.1s0.8-0.3,1.1,0l2.1,2.1l4.8-4.8c0.3-0.3,0.8-0.3,1.1,0s0.3,0.8,0,1.1l-5.3,5.3C10.1,14.3,9.9,14.4,9.7,14.4z"/></g></svg>' document.getElementById('add').addEventListener('click', function () { var value = document.getElementById('item').value // 若輸入框不爲空,則添加事項並重置輸入框 if (value) { addItem(value) document.getElementById('item').value = '' } }) function addItem(text) { // 依次創建 li / div / button 標籤,並添加到 id = 'not' 的 ul 標籤中 var list = document.getElementById('not') var item = document.createElement('li') item.innerHTML = text var buttons = document.createElement('div') buttons.classList.add('buttons') var remove = document.createElement('button') remove.classList.add('remove') remove.innerHTML = removeSVG remove.addEventListener('click', removeItem) var complete = document.createElement('button') complete.classList.add('complete') complete.innerHTML = completeSVG complete.addEventListener('click', completeItem) buttons.appendChild(remove) buttons.appendChild(complete) item.appendChild(buttons) // 插入到 ul 標籤第一個子節點的前面 list.insertBefore(item, list.childNodes[0]) } function removeItem() { //獲取 li var item = this.parentNode.parentNode // 獲取 ul var parent = item.parentNode parent.removeChild(item) } function completeItem() { // 獲取 li var item = this.parentNode.parentNode // 獲取 ul var parent = item.parentNode // 獲取 ul 標籤的 id 值 var id = parent.id // 如果此時鼠標事件觸發在未完成事項組(.not),則切換到已完成事項組(.one),否則相反。 // 前者刪除該元素,後者添加該元素 var target = id === 'not' ? document.getElementById('done') : document.getElementById('not') parent.removeChild(item) target.insertBefore(item, target.childNodes[0]) }