效果图:
前言:
实现你的代办事项,为自己制作一个备忘录小插件。这里先介绍一下弹性布局的概念,更利于完成后续的制作。 在JavaScript中,"弹性布局"通常指的是CSS中的Flexbox布局,而不是JavaScript本身。Flexbox是一种用于在容器中布局子元素的布局模型,它使得在不同大小的屏幕上以及不同的设备上更容易实现灵活的布局。
Flexbox布局基于"弹性盒子"的概念,它包括一个父容器(称为"flex container")和多个子元素(称为"flex items")。通过在父容器上应用display: flex;或display: inline-flex;样式,可以创建一个弹性容器,并通过设置父容器的属性来定义子元素在其中的布局行为。
<style>
.box{
width: 600px;
height: 200px;
background: #1ac614;
justify-content: space-between;
align-items: center;
/* flex-direction: column; */
}
.item{
background: red;
height: 100px;
}
.item2{
background: #0b6527;
}
.item1{
width: 200px;
}
.item2{
width: 200px;
}
</style>
</head>
<body>
<div class="box">
<div class="item item1">1</div>
<div class="item item2">2</div>
</div>
</body>
根据代码所示,创建一个box的父容器用于储存两个item的子容器,这时会发现div下的item是块级元素,不在同一行。
这里要将两个块级元素直接归并到同一行之中,就可以使用display: flex;进行弹性布局,这时候便会归并到同一行中
justify-content:定义了子元素在主轴上的对齐方式。align-items:定义了子元素在交叉轴上的对齐方式。
justify-content: space-between 空白填充两个子容器之间的距离
align-items: center; 实现交叉轴的居中
正文
<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>
</body>
建立id为app中存放一个container容器。
-
<div class="input-group">:这是一个输入框和按钮的容器,具有input-group类。<div class="label">待办事项</div>:一个简单的文本标签,显示"待办事项"。<input type="text" class="content" id="newTodo">:一个文本输入框,具有content类和id="newTodo"。用户可以在此输入新的待办事项。<button class="btn">新增</button>:一个按钮,用于向待办事项列表中添加新项目。
-
<div class="list">:这是待办事项列表的容器,具有list类。<ul id="todo-list">:一个无序列表,具有todo-list的ID。这个列表用于显示待办事项。
用CSS进行布局。
body { height: 100vh; display: flex; justify-content: center; align-items: center; }
用弹性布局使容器进行居中。子容器默认继承弹性父容器的100%的高。
.title { text-align: center; margin: 10px; }
使块级元素居中,即title居中。
.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 #eee;
}
.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 #aaa;
font-size: 20px;
text-align: center;
border-radius: 10px;
cursor: pointer;
}
text-align: center;:使关闭按钮内的文字水平居中显示。border-radius: 10px;:设置关闭按钮的边框半径为10像素,使其呈现圆角效果。cursor: pointer;:当鼠标悬停在关闭按钮上时,鼠标样式会变为指针形状,表示该按钮可点击。 设置关闭按钮的效果,获得效果
JS部分(重点)
该如何展示新增按钮下有多少行列表,如何储存?这里可以使用数组来进行储存。
var todoData = []
var addTodo = document.querySelector('.btn') // 按钮
var todoList = document.getElementById('todo-list')
定义一个数组,并获取按钮和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()
}
}
if (document.getElementById('newTodo').value.trim() !== ''):这一行代码首先通过document.getElementById('newTodo')获取了一个id为newTodo的DOM元素,然后使用.value获取该元素的值,.trim()方法用于去除字符串两端的空格。这个条件语句检查输入框中是否有非空字符。todoData.push({ id: Math.floor(Date.now()), title: document.getElementById('newTodo').value, completed: false }):如果输入框中有非空字符,就将一个包含待办事项信息的对象推入名为todoData的数组中。这个对象包含了一个由当前时间戳生成的唯一id,输入框中的内容作为标题,以及completed属性设置为false表示待办事项尚未完成。
// 将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
}
function render():这是一个名为render的函数,用于将todoData中的数据渲染出来。var str = '':声明了一个空字符串str,用于存储待办事项列表的HTML代码。todoData.forEach(function (item) { ... }):使用forEach方法遍历todoData数组中的每个元素,对每个元素执行一段函数。- 在遍历函数中,将每个待办事项的信息拼接成HTML字符串,并添加到
str中。每个待办事项都被包裹在<li>标签内,包含一个复选框、待办事项标题和一个关闭按钮。 todoList.innerHTML = str:最后,将拼接好的HTML字符串赋值给todoList元素的innerHTML属性,以便将其显示在页面上。
以此来完成函数的渲染。