【JavaScript】實現 TodoList 移動端頁面

效果預覽: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])
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章