js实现一个todolist(待办事项),你也可以拥有一个简易记事本!

971 阅读7分钟

前言:

相信很多小伙伴们每天都有自己的计划,学习计划,生活计划安排,大家可能会把它写在自己的备忘录里,以提醒自己这一天需要完成的事情,那么大家有没有这个备忘录是怎么实现的呢?有没有想过自己动手实现这样一个todolist呢? 今天小编就带大家用js来一起实现这样一个简易的备忘录,你也可以自己拥有一个简易的记事本!

首先todolist是什么?

Snipaste_2024-04-25_15-28-53.png

这个网页的功能就是:
1.在输入栏中输入内容回车确定后会加入到下面的待办事项中
2.勾选选择框,可以记录已完成的事件
3.点击删除按钮,可以删除待办事项中的完成事件

Snipaste_2024-04-25_15-29-36.png

小伙伴们感兴趣的话可以自行去感受一下,可以用这个记录自己每天要完成的计划----------->todomvc.com/examples/ja…

话不多说,开干!

html部分:

大体框架为:使用 <div id="app" class="container"> 作为主要容器定义一个大盒子(container)将输入事项(input-group)和代办事项(list)这两个盒子包含起来。

  • <div class="input-group"> 包含输入框和添加按钮,作用是输入和添加待办事项。
  • <div class="list"> 包含 <ul id="todo-list"></ul>,用于展示待办事项列表。
<body>
    <div id="app" class="container">
        <h2 class="title">Todo List</h2>
        <div class="input-group">
            <div class="label">待办事项</div>
            <input type="text" class="content" id="newTodo">
            <button class="btn">新增</button>
        </div>
        
        <div class="list">
            <ul id="todo-list">    
            </ul>
        </div>
    </div>
    <script src="./index.js"></script>
</body>

css部分:

li{
    list-style: none;
}
*{
    margin: 0;
    padding: 0;
}

body{
    height: 100vh;
    display: flex;
    justify-content: center;
    align-items: center;
}


.container {
    width: 400px;
    height: 400px;
    border: 1px solid black;

}
.title {
    text-align: center;/*控制文本水平居中*/
    margin: 10px ;
}
.input-group {
    display: flex;
}
.label {
    padding: 5px 10px 5px 10px; /*上右下左*/
}
.btn{
    padding: 5px 10px ;
    margin-left: 10px;
}
.content{
    flex: 1;
}
.item:nth-child(1){
    margin-top: 20px;
}
.item{
    border-bottom: 1px solid rgb(12, 29, 28);
}

.flex{
    display: flex;
    width: 90%;
    margin: 0 auto;
    align-items: center;
}
.item-check{
    margin-right: 20px;
}
.item-content{
    flex: 1;
}
.close{
    width: 30px;
    height: 30px;
    border: 1px solid black;
    font-size: 20px;
    text-align: center;
    border-radius: 10px;
    cursor: pointer;
}

重点是弹性布局(flex):通过给父容器设置 display: flex,然后通过 flex、justify-content、align-items 等各种属性,提供一种更加有效的方式来对一个容器中的子元素进行排列、对齐和分配空白空间,实现灵活的响应式布局。

body{
    height: 100vh;
    display: flex;
    justify-content: center;
    align-items: center;
}
  1. height: 100vh; 设置<body>元素的高度为其视口(viewport)高度的100%。vh是一个视口单位,表示视口高度的1%。这意味着无论用户屏幕的尺寸如何,<body>元素都会尽可能填满整个屏幕的高度。
  2. display: flex;<body>元素的显示方式设置为Flexbox布局。
  3. justify-content: center; 在Flexbox布局中,justify-content属性用于控制主轴(默认为水平方向)上子元素的对齐方式。center值表示子元素将在主轴上居中。这意味着<body>元素的直接子元素将在水平方向上居中。
  4. align-items: center; center值表示子元素将在交叉轴上居中。这意味着<body>元素的直接子元素将在垂直方向上居中。
Flex布局的好处:

1.简单易懂:与传统的布局方式相比,Flex布局的语法和理解起来更加简单,容易上手。
2.弹性和自适应:Flex布局能够自动适应不同尺寸的屏幕,让页面更具有弹性。
3.等高布局:Flex布局可以方便地实现多列等高布局。
4.对齐和排序:Flex布局支持各种对齐方式,包括水平和垂直对齐,并且可以通过设置order属性对子元素进行排序。
5.可以与传统布局结合使用:Flex布局并不是完全取代传统的布局方式,它可以与传统布局方式结合使用,实现更灵活的布局效果。

接下来就是重中之重js部分的实现:

需要实现的功能:
1.获取用户在newTodo输入框中的输入信息,新增待办事项

思路:首先获取新增按钮元素addTodo对addTodo设置监听器,当新增按钮被点击后触发addNewTdo()函数添加待做事项;创建一个数组存取内容输入框输入的内容;获取ul标签元素,以便添加li标签;通过document.getElementById('newTodo').value.trim()获取输入框的内容,然后判断是否为空,如果不为空则push添加在数组内;通过reader()函数渲染新增加的li标签内容。

2.点击待办事项左边的按钮可以将待办事项标记为已完成事项

3.点击待办事项右边的删除按钮可以删除该待办事项
思路:定义lis获取所有的li标签,遍历lis,取得每个li标签中的span元素和p元素,为span元素添加事件监听,当鼠标按下时则将该li标签移除。并获取此时p元素中的内容在数组todoData中的位置,在数组中移除该元素。

var todoData = []

var addTodo = document.querySelector('.btn')//按钮
var todoList = document.getElementById('todo-list')//列表   

function addNewTodo() {
    //获取input中的内容
    if (document.getElementById('newTodo').value.trim() !== '') {
        todoData.push({
            id: Math.floor(Date.now()),
            title: document.getElementById('newTodo').value,
            completed: false
        })
        //渲染新的li
        render();
        //删除选中的标签
        removeTodo();
        
    }
}

function removeTodo() {
    
    const lis=document.querySelectorAll('li')//获取所有的li标签

    lis.forEach(function(li){
        
        var spans=li.querySelector('span')//获取当前li下的span标签
        
        var ps=li.querySelector('p')//获取当前li下的p标签
        spans.addEventListener('click',function(){//点击span标签时删除当前li标签,为span添加点击监听事件
            li.remove();//当点击span标签时,移除当前li标签
            var index=todoData.indexOf(ps.textContent);
            todoData.splice(index,1);
        })
    })
}


addTodo.addEventListener('click', addNewTodo)

//将todoData中的数据渲染出来
function render() {
    var str = ''
    todoData.forEach(function (item) {
        str += `
        <li class="item">   
                    <div class="flex">
                        <input type="checkbox" class="item-check">
                        <p class="item-content">${item.title}</p>
                        <span class="close">X</span>
                    </div>
                </li>
        `
    })
    todoList.innerHTML = str

}

主要函数:

一、 定义了一个名为 render 的函数,其主要目的是基于 todoData 数组来渲染一个待办事项列表(todo list)到 todoList 这个HTML元素中。

  1. todoData.forEach(function (item) {: 使用 forEach 方法遍历 todoData 数组。对于数组中的每一个 item,都会执行以下的函数。
  2. str += ``...``;: 这里使用模板字符串(由反引号 ` 包围)来拼接HTML代码,并将其添加到 str 字符串中。这个HTML代码代表一个待办事项列表项(list item),其中包含了: 一个复选框(input 类型为 checkbox)用于标记待办事项是否完成。 一个段落(p)显示待办事项的标题(item.title)。 一个关闭按钮(span),其文本为 "X",用于可能的后续操作,比如删除该待办事项。

二、 定义了一个名为 removeTodo 的函数,其主要目的是为待办事项列表中的每一个待办事项项(<li> 标签)添加一个删除功能。当用户点击某个待办事项项旁边的关闭按钮(<span> 标签)时,该待办事项项将从列表中移除,并且从 todoData 数组中删除相应的数据。

  1. const lis = document.querySelectorAll('li');: 使用 querySelectorAll 方法获取页面上所有的 <li> 标签,并将它们存储在 lis 变量中。
  2. lis.forEach(function(li) {: 使用 forEach 方法遍历每一个 <li> 标签。
  3. var spans = li.querySelector('span');: 对于当前遍历到的 <li> 标签,使用 querySelector 方法获取其内部的 <span> 标签(关闭按钮),并将其存储在 spans 变量中。
  4. var ps = li.querySelector('p');: 对于当前遍历到的 <li> 标签,使用 querySelector 方法获取其内部的 <p> 标签(显示待办事项的标题),并将其存储在 ps 变量中。
  5. spans.addEventListener('click', function() {: 为当前遍历到的 <span> 标签(关闭按钮)添加点击事件监听器。
  6. li.remove();: 当点击事件发生时,移除当前遍历到的 <li> 标签(即删除该待办事项项)。
  7. var index = todoData.indexOf(ps.textContent);: 在 todoData 数组中查找当前 <p> 标签的文本内容(待办事项的标题)的索引位置。
  8. todoData.splice(index, 1);: 使用 splice 方法从 todoData 数组中移除找到的待办事项。

好啦,今天的分享就到这里啦,感兴趣的小伙伴们可以自己去动手实现实现,做一个属于自己的todolist!如果文中有写的不足的地方还请各位大佬批评指正。如觉得本文对你有帮助的话,欢迎点赞收藏,感谢!。