likes
comments
collection
share

用js手搓一个todoList

作者站长头像
站长
· 阅读数 40

前言

todoList是什么

用js手搓一个todoList 那么这个网页主要实现的功能就是:

  1. 在输入框输入内容敲回车会添加到代办区域
  2. 点击删除按钮可以将代办区域完成事项删除
  3. 点击复选框,勾选已完成事项

用js手搓一个todoList 大家可以自行去感受一下,经常要写计划的同学也可以用这个来记录待完成的事情

----------->todomvc.com/examples/ja…

实现代码

html部分

<body>
    <div id="app" class="container">
        <h2 class="title">todos</h2>

        <div class="input-group">
            <div class="label">待办事项</div>
            <input type="text" class="content" id="newTodo" placeholder="What you need to be done?">
            <button class="btn">新增</button>
        </div>

        <div class="list">
            <ul id="todo-list">
            </ul>
        </div>
    </div>

    <script src="./index.js"></script>
</body>

CSS部分

* {
    margin: 0;
    padding: 0;
}

li {
    list-style: none;
}

body {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif;
    background: #f5f5f5;


}

.container {
    width: 500px;
    height: 500px;

}

.title {
    text-align: center;
    margin: 10px;
    font-style: 30px;
    width: 100%;
    font-size: 80px;
    font-weight: 200;
    color: #b83f45;
}

.input-group {
    display: flex;
    font-size: 20px;
}

.label {
    padding: 5px 10px 5px 10px;
}

.btn {
    padding: 5px 10px;
    margin-left: 10px;
    margin-right: 1px;
}

.content {
    flex: 1;
    font-size: 24px;

}

.item:nth-child(1) {
    margin-top: 20px;
}

.flex {
    display: flex;
    width: 90%;
    margin: 0 auto;
    align-items: center;
}

.item-check {
    margin-right: 20px;
}

.item {
    border-bottom: 1px solid #eee;
}

.item-content {
    flex: 1;
}

.close {
    width: 30px;
    height: 30px;
    border: 1px solid #000;
    font-size: 20px;
    text-align: center;
    border-radius: 10px;
    cursor: pointer;
}

js部分

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();
    }
}

// 将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" data-id="${item.id}" >×</span>
                </div>
            </li>
        `
    })
    todoList.innerHTML = str;

}

addTodo.addEventListener('click', addNewTodo);

todoList.addEventListener('click', delete_list);


function delete_list(event) {

    if (event.target.classList.contains('close')) { // 判断点击的元素是否是关闭按钮
        var id = event.target.dataset.id; // 获取关闭按钮的 data-id 属性值
        for (var i = 0; i < todoData.length; i++) {

            if (todoData[i].id == id) {
                todoData.splice(i, 1); // 根据 id 从数组中删除对应的待办事项
            }
        }
        render(); // 重新渲染待办事项列表
    }
}

重难点思路解析

  1. html部分的搭建过程,小白同学可以先把内容写死,比如ul中的li,写死一个学习/看电影...,后续编写js部分我们就会发现,谁也不知道后续会发生什么,自然会去更改这一部分的代码。
  2. placeholder 是一个 HTML 特性,用于为输入字段提供提示信息。 它的作用是在输入字段为空时显示一些提示文本,以指导用户输入合适的内容。
  3. css部分,html中许多标签自带内外边距,我们可以通过通配符将内外边距全部改为0,后续需要添加边距的标签可以自行添加。
  4. display: flex;弹性布局,之前我们有写过一些需要居中对齐的方法,通过各种定位方式,这里我们选用弹性布局就会发现,他实现起来代码更加简洁,用途更加明确。弹性容器默认的主轴为x轴,子容器全部在主轴上对齐,子容器默认继承弹性父容器百分之百的高,不管是不是块级元素,他们都会被放置在一行去。justify-content主轴方向设置,align-items:副轴方向设置。
  5. flex 属性用于定义元素在剩余空间中的分配比例。flex: 1 表示该元素将占用剩余空间的一份。具体来说,当多个元素都设置了 flex 属性时,它们将按照各自的比例来分配剩余空间。flex: 1 通常用于确保某个元素在 Flex 容器中具有相同的伸展能力,与其他元素一起均匀地分配剩余空间。
  6. height: 100vh; 是一个 CSS 样式属性,它表示将元素的高度设置为视窗高度(viewport height)的 100%。视窗高度是指浏览器窗口可见区域的高度。通过这种方式,我们就不需要写body的height百分百,再写html的height百分百

最主要的实现思路还是在js部分

  • 我们需要获取用户在input中输入的内容,但是不排除用户直接敲了空格,因此我们需要去除空值:if(document.getElementById('newTodo').value.trim() != '')
  • 定义一个数组,用于存放用户输入的内容,当然这个数组中的内容,以对象的形式存在,这样我们可以对每一个内容进行编号,设置一个id属性,有什么东西是独一无二的呢?-->时间,因此我们可以获取当前时间并对其进行向下取整,获取一个独一无二的时间戳,获取到了内容之后,我们就需要将这个内容写进ul中的li,因此接下来就需要对li进行渲染,定义一个render函数做这件事情
  • render中如何实现呢?定义一个空的字符串,通过遍历的方式,获取到数组中的每一个对象,用字符串拼接的方式,将li拼接进去,但是这里面的内容是不一样的,我们通过${}变量插值,将对象中的title(用户输入的内容)插入li,以及span标签中也添加了其他的属性,因为我们需要在点击x时,实现删除这个li的功能,我们需要精确识别到是哪一个span。最后通过todoList.innerHTML = str;将这个字符串插入html的ul中
  • event.target.classList.contains('close')可以判断点击的元素中是否有类名为close的标签,并获取这个标签的data-id属性值,然后通过遍历的方式,查看数组中是否有id与这个data-id相等的值,如果有,那就找到了这一条将其删除,再调用render函数重新渲染页面。

效果

用js手搓一个todoList

用js手搓一个todoList

用js手搓一个todoList

结语

通过这个案例,你是否学到一些实现思路呢?有了思路,再用代码的形式将思路转化为功能,在手敲完成这个功能之后是否获得满满的成就感?

转载自:https://juejin.cn/post/7361468008529068084
评论
请登录