基于浏览器localStorage作为数据库完成todolsit项目

news2024/9/24 9:25:04

一、文章内容

TodoList结构搭建HTML代码

TodoList样式编写Css代码

TodoList行为表现JavaScript代码

二、项目展示

项目介绍

Todolist是一个基于B/S模式开发的待办事项软件,主要功能是离线记录用户的待办事项和已经完成的事情,基于html+css+js实现,涉及到的知识主要是事件监听和数据缓冲技术.

项目展示GIF

演示效果new.gif

图1 项目功能展示

项目中的亮点:

  1. 点击代办事项可以让输入框获取焦点,我愿称之为:梦幻联动效果.
  2. 在输入框里按下回城键调用add()函数,自动判断:自动检测.
  3. 在左下角有一个“我要到上面”的标签,点击就可以快速回到顶部,我称为:一键返航.

三、代码细节

Html部分

相信大家在学习过前导课的基础上我们学习下面代码会轻松很多,不过我也会一行一行给大家解释的。
我们讲html页面分为顶部和内容部分,也就是header和section部分,第一个header包裹的内容就是todolist的头部,如图2所示.

image.png

图2 todolist顶部

夹在header和footer中间的section为页面主题部分,也就是项目展示的地方,里面包含了todo和done列表,如图3所示.

image.png

图3 网页中心界面

html框架搭建总体比较简单所以大家可以根据自己的想法设计,或者跟着我这个框架敲一遍.下面是所有的html代码:

  <header>
    <section>
      <div id="form">
        <label for="title">
          todo
        </label>
        <input type="text" id="title" placeholder="输入todolist">
      </div>
    </section>
  </header>
  <section>
    <h2>需要进行的事情<span id="todocount">0</span></h2>
    <ol id="todolist" class="demo-box"></ol>
    <h2>已经完成的事情<span id="donecount">0</span></h2>
    <ul id="donelist"></ul>
  </section>
  <footer>
    <a href="#top" id="mao">我要到上面</a>
  </footer>

Css样式代码

当然要让css和html联动必须在html中引入自己的css文件,语法如下<link rel="stylesheet" href="main.css">因为我的css样式新建了文件,并且跟index.html在同根目录下,所以可以这样引入,路径不同的读者可以自己修改src的属性值.
如果自己有设计的同学可以直接看下面JavaScript逻辑代码了,这块主要负责美化样式.

body{}选择器是将body标签选中,将内外边距都设置为0,方便后期开发,如果不设置该属性会默认有偏移.剩下俩个是整个网页的字体大小跟背景色全局生效.

html,body{}这个选择器里的属性只有一个scroll-behavior这个在前导课里讲过,功能使得页面滑动平滑.

header{}这个选择器设置了顶部的高度和背景色.

section{}选择器设置了主要内容居中显示,margin:0 auto;auto是关键.

#mao{}id选择器主要通过浮动设置了一键返航的位置.

label{}选择器是待办事项这几个字的位置也是使用了浮动,这是左浮动,通过line-hight设置垂直方向的字体位置,如果跟父级元素高度一样,里面的字就可以实现垂直居中了.cursor:pointer;设置了鼠标悬浮的样式,我记得有6种样式,大家可以自己尝试.

header input{}组合选择器主要负责的是输入框的内容,这里设置了右浮动,同时设置了宽度50%,意思是只占父级元素的一半宽度,text-indent是输入框的缩进,单位像素,自己可以测试一个合适的value,我选择10个像素,border-radius: 5px; 这个属性是输入框的圆角,值越大越⚪.box-shadow: 0 1px 0 rgba(255,255,255,0.24), 0 1px 6px rgba(0,0,0,0.45) inset; 这个属性设置了输入框的盒子阴影,具体参数大家可以去看看CSS box-shadow 属性 (w3school.com.cn).border:none; 这样设置输入框的外边框就没了.

input:focus{}伪类选择器中outline-width: 0; 设置了输入框的边框,也就是当输入框获取焦点,默认是有边框的,这样设置就可以解决这个问题.

h2{}选择器标签只加了一个定位属性,原因是为了span可以很好的定位.

span{}选择器是todolist和donelist的个数,也就是最左边哪个圆点,line-height: 20px; text-align: center;是让文字水平和垂直居中的,其他属性都在上面介绍过,所以不一一介绍了.

ol,ul{}选择器是todolist和donelist列表外部标签list-style: none; 该属性可以让有序列表和无序列表的数字和圆点消失,加强了美观.

li input{}选择器是每个任务item的选择框样式,设置了position:absolute,进行了元素定位,然后设置了鼠标悬浮的样式.

li{}选择器设置了相对的位置,border-radius: 3px;
border-left: 6px solid #FFB800;
border-right : 6px solid #FFB800;
分别设置了选择框的左右边框,和item的圆角.

li:hover{}伪类选择器设置了todolist和donelist中item触摸上去颜色变为蓝色color:#01AAED;

ul li{}组合选择器设置了完成item的透明色和左右边框的颜色border-left: 5px solid #c2c2c2;
border-right: 5px solid #c2c2c2;
opacity: 0.5;

最后使用@media screen and (min-width){}选择器设置了自适应布局.
下面是css的所有代码:

body{
    padding: 0;
    margin: 0;
    font-size: 16px;
    background:#dddddd;
}
html,body{
    scroll-behavior: smooth ;
}
header{
    height: 50px;
    
    background: #333;
}
section{
    margin: 0 auto;
}
#mao{
    
    float:right;
    margin-right: 40px;
    margin-bottom: 20px;
}
label{
    float: left;
    width: 100px;
    line-height: 50px;
    color: #DDD;
    font-size: 24px;
    cursor:pointer;
}
header input{
    float: right;
    width: 50%;
    height: 25px;
    margin-top: 12px;
    /* 所经 text_indent */
    text-indent: 10px; 
    border-radius: 5px;
    box-shadow: 0 1px 0 rgba(255,255,255,0.24), 0 1px 6px rgba(0,0,0,0.45) inset;
	border:none;
}

input:focus{
    outline-width: 0;
}
h2{
    position: relative ;
}
span{
    position: absolute;
    top: 10px;
    right: 5px;
    display: inline-block;
    padding: 0 5px;
    height: 20px;
    border-radius: 20px;
    background-color: seagreen;
    line-height: 20px;
    text-align: center;
    color:whitesmoke;
    font-size: 14px;
}
ol,ul{
    padding: 0;
    list-style: none;
}
li input{
    position:absolute;
    top:2px;
    left: 10px;
    width: 22px;
    height: 22px;
    cursor: pointer;
} 
li{
    height: 32px;
    line-height: 32px;
    background-color: #fff;
    position: relative;
    margin-bottom: 10px;
    padding: 0 45px;
    border-radius: 3px;
    border-left: 6px solid #FFB800;
    border-right : 6px solid #FFB800;
}
li:hover {
    color:#01AAED;
}
 
ul li{
	border-left: 5px solid #c2c2c2;
    border-right: 5px solid #c2c2c2;
	opacity: 0.5;
    
}
@media screen and (max-device-width: 620px) {section{width:96%;padding:0 2%;}}
@media screen and (min-width: 620px) {section{width:600px;padding:0 10px;}}
 

JavaScript逻辑代码

站在产品经理角度分析:如何在完成基本需求的基础上,使得用户体验更好?

答案:1.点击todolist(待办事务)输入框自动获取焦点.
2.在输入框里回车即可提交事务,不必加button.3.在任务数量较多的时候提供一家返回功能.

当然在满足上述功能后我们需要弄清楚JavaScript的逻辑代码,其实只有todolist和donelist需要我们更新,只要2者发生变化我们就需要load()加载一次,所以load()需要写为一个函数多次调用,再其次就是将add()按键触发也写为一个函数方便,在里边修改规则,这是简单的解耦,最后我门将pd()和pd2()封装为俩个函数分别将不同checkbox发出的按键逻辑进行代码编写,方便修改对应逻辑.
在明白需求后开始写代码,每个函数都写了一个小标题进行了函数解释,最后将文末的俩行监控代码加进去组成js代码引入到html页面里即可.

未命名文件.png

图4 简易框架图

只要打开页面就要启用监听事件,将load()加载,这样做的好处是无论你是第一次打开网站,还是第二次都可以准确无误的加载item.语法是:**window.addEventListener(“load”, load); //页面加载完毕调用load函数 **

然后监听输入框按键,语法规则document.addEventListener(“keyup”, add); 然后编写对应的add()函数即可.

函数解释load():

第一行和第二行是获取todolist和donelist个数的元素(小圆点),方便下面对数量进行更新,使用localStorage.todo读取本地缓存中的todo数据,如果有数据,进行数据解析将缓冲解析为JavaScript的数组,然后声明一个todohtml变量保存item数据=》然后根据todo的长度for循环,根据规则加li标签最后使用JavaScript操作dom找到todolist的元素将innerhtml赋值为todohtml即可将todolist渲染完成.最后简单判断一下todo的长度,如果有长度,将控制item数量的元素找到然后修改value,如果没长度也就是第一次打开默认为0!todolist和donelist渲染方式一样,我就不多解释了,请认真结合文字读这段代码.你一定可以读懂.

 function load(){
    todocount = document.getElementById("todocount");
    donecount = document.getElementById("donecount");
    if(localStorage.todo){
        todo = JSON.parse(localStorage.todo);
        var todohtml = "";
        for(var i = 0 ; i < todo.length; i++){
            todohtml += '<li><input type="checkbox" cheched onclick="pd(this)" value="'+ i +'" name="' + todo[i]  + '">' + todo[i] + '</li>';
        }
        document.getElementById('todolist').innerHTML = todohtml;
        if(todo.length!=0) {
            todocount.innerHTML = todo.length;
        } else{
            todocount.innerHTML = 0;
        }
    }
    
    if(localStorage.done){
        done = JSON.parse(localStorage.done);
        var donehtml = "";
        for(var i = 0 ; i < done.length; i++){
            donehtml += '<li><input type="checkbox" cheched onclick="pd2(this)" value="'+ i   +'" name="' + done[i]  + '">' + done[i] + '</li>';
        }
        document.getElementById('donelist').innerHTML = donehtml;
        if(done.length!=0){
            donecount.innerHTML = done.length;
        }else{
            donecount.innerHTML = 0 ;
        }
}
}

函数解释add():

add()函数是当回车键触发且判断加入的事件不为空更新本地缓冲的一个函数并且load().

函数第一行使用JavaScript操作dom获取到input输入框元素,然后判断按键是否为13也就是回车键的Unicode码==13 并且输入框的内容不为空,然后将todo使用堆栈操作添加输入框的内容,接着更新本地缓冲(需要json变为字符串),然后将输入框内容置为空,然后就可以加载load()函数更新页面了.如果不满足条件弹出alert信息框.
完整代码如下:

function add(e){
    info = document.getElementById('title') ;
    if(e.keyCode == 13 && info.value != ''){
        todo.push(info.value);
        localStorage.todo = JSON.stringify(todo);
        info.value = '';
        load();
    }else if(e.keyCode == 13 && info.value == ''){
        alert('输入内容提交');
    }
}

函数解释pd():

细心的读者一定发现这个函数在todolist的每一个item里有个checkbox然后绑定了一个onclicked的事件,当你选择该选择框的时候就会调用pd()函数,该函数是将todolist里的元素删除并且添加到donelist的.

done.push(e.name)将本元素的name加到donelist里,为什么可以这样操作? 因为在load()函数里写了
'<li><input type="checkbox" cheched onclick="pd(this)" value="'+ i +'" name="' + todo[i] + '">' + todo[i] + '</li>';

看到name属性的值是todo[i]item的值,所以可以直接push,然后在todolist里删除该item使用,splice函数,该函数专门为数组设计的用法挺多,详细了解的读者可以自行百度,因为input的value记录的是该item的index下标所以可以直接pareint转换,既然todo和done都更新了,我们接着将浏览器缓冲更新一下就是**localStorage.done = JSON.stringify(done);

localStorage.todo = JSON.stringify(todo);** 这样,接着在列表改动后继续load()重载一下,下面是代码:
function pd(e){
     
    done.push(e.name);
    todo.splice(parseInt(e.value),1);
    localStorage.done = JSON.stringify(done);
    localStorage.todo = JSON.stringify(todo);
    load(); 
}
函数解释pd2():

既然有pd()肯定页有pd2(),一个操作todo里面的checkbox,一个操作done里面的checkbox,好了言归正传,pd2()和pd()操作逻辑一样,但是实体却不一样,一个是todo数组push一个是done数组push,读者可以自行比较,这段代码相对简单,在todo和done数组修改完毕,接着就是更新本地缓冲了,然后load()函数.

function pd2 (e){
     
    done.splice(parseInt(e.value),1);
    todo.push(e.name);
    localStorage.done = JSON.stringify(done);
    localStorage.todo = JSON.stringify(todo);
    load(); 
}

将上述代码和下面这俩行代码组合成一个js文件就是JavaScript所有代码了.

window.addEventListener("load", load); //页面加载完毕调用load函数 
document.addEventListener("keyup", add); //按键监听

能读到这里的小伙伴属实不容易,相信你能坚持这么久你一定可以自己独立开发todolist程序了,恭喜你呀.

四、参照文献

CSS 简介 (w3school.com.cn)

JavaScript 教程 | 菜鸟教程 (runoob.com)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1534280.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

TSINGSEE青犀AI智能分析网关V4酿酒厂安全挂网AI检测算法

在酿酒行业中&#xff0c;安全生产一直是企业经营中至关重要的一环。为了确保酒厂生产过程中的安全&#xff0c;TSINGSEE青犀AI智能分析网关V4的安全挂网AI检测算法发挥了重要作用。 TSINGSEE青犀AI智能分析网关V4的安全挂网检测算法是针对酒厂里酒窖挂网行为进行智能检测与识…

Linux第82步_“gpio子系统”下的使用KEY开关灯

使用新字符设备驱动的一般模板和“gpio子系统”&#xff0c;以及设备树&#xff0c;驱动KEY和LED。 1、在stm32mp157d-atk.dts文件中添加“gpio_led”和“key0”节点 打开虚拟机上“VSCode”&#xff0c;点击“文件”&#xff0c;点击“打开文件夹”&#xff0c;点击“zgq”&…

设置客户端桌面壁纸 文件夹重定向

域策略-设置客户端桌面壁纸 1/服务器管理器组策略管理-gwy.com-Defait Domain Policy-右击编辑 2/用户配置-首选项-置windows设置-文件夹-右击文件夹-创建-C:\bgp-应用 3/在客户端策略更新-gpupdate /force 命令符-查看是否正确 4/服务器创建c:\image\R-C.jpg&#xff0c;共享文…

G - Find a way

题目分析 1.双重bfs,遍历两个起点求最短路再计算总和即可 2.唯一的坑点在于对于一个KFC&#xff0c;两人中可能有一个到不了&#xff0c;所以还要对到不了的点距离做处理 #include <bits/stdc.h> using namespace std; using ll long long; const int N 220;struct pos…

[python]bar_chart_race绘制动态条形图

最近在 B 站上看到了一个宝藏 up 主&#xff0c;名叫 "Jannchie见齐"&#xff0c;专门做动态条形图相关的数据可视化。 可以看到做出的效果还是很不错的&#xff0c;但工具使用的是 JS&#xff0c;不是 Python&#xff0c;于是尝试搜索了一下&#xff0c;看看 Python…

读取pdf文件转为txt文件,使用正则表达式删除页码

通过下述链接中的代码python 读取pdf中的文本&#xff0c;读取pdf的文字到txt文本中。 txt文本中&#xff0c;包含pdf的页码信息&#xff0c;使用如下代码删除pdf的页码 下述是包含页码信息的一段文本&#xff0c;在其中给出了4中不同格式的页码信息。 text ""&qu…

机器视觉学习(四)—— 图像的色彩

目录 一、图像的基础知识 二、NumPy模块 三、图像色彩变化 3.1 RGB图像的分通道显示 3.2 HSV图像的分通道显示 一、图像的基础知识 总结的笔记&#xff1a; """ 二值图: 每个像素取值 0或1,图像显示出来只有黑白色; 黑色:0 白色:1 灰度图: …

CSDN学习笔记总索引(2024)——我的创作纪念日(1024)

从2021-05-21至2024-03-21&#xff0c;我的CSDN博文学习笔记中&#xff0c;收集并展示浏览阅读&#xff0c;点赞收藏评论等数据&#xff0c;以浏览阅读量排逆序展示。 (笔记模板由python脚本于2024年03月21日 10:07:07创建&#xff0c;本篇笔记适合熟悉Python&#xff0c;对其基…

spring boot3登录开发-2(2短信验证码接口实现)

⛰️个人主页: 蒾酒 &#x1f525;系列专栏&#xff1a;《spring boot实战》 &#x1f30a;山高路远&#xff0c;行路漫漫&#xff0c;终有归途 目录 写在前面 上文衔接 内容简介 短信验证码接口实现 1.依赖导入 2.接口分析 3.实现思路 3.功能实现 创建发送短信…

PTA L2-041 插松枝 代码附注释

人造松枝加工场的工人需要将各种尺寸的塑料松针插到松枝干上&#xff0c;做成大大小小的松枝。他们的工作流程&#xff08;并不&#xff09;是这样的&#xff1a; 每人手边有一只小盒子&#xff0c;初始状态为空。每人面前有用不完的松枝干和一个推送器&#xff0c;每次推送一…

一些刷题需要用的大数据

无符号版本和有符号版本的区别就是有符号类型需要使用一个bit来表示数字的正负。 如果需声明无符号类型的话就需要在类型前加上unsigned。 整型的每一种都分为&#xff1a;无符号&#xff08;unsigned&#xff09;和有符号&#xff08;signed&#xff09;两种类型&#xff08;f…

【小沐学AI】Google AI大模型的一点点学习(Python)

文章目录 1、Google AI简介1.1 Google AI Studio1.2 Bard1.3 PaLM1.4 Gemini1.5 Gemini API1.6 Vertex AI1.7 Gemma 2、Google AI开发2.1 快速入门2.1.1 配置开发环境2.1.2 列出所有模型2.1.3 从文本输入生成文本2.1.4 从图像和文本输入生成文本2.1.5 聊天对话 结语 1、Google …

(vue)新闻列表与图片对应显示,体现选中、移入状态

(vue)新闻列表与图片对应显示&#xff0c;体现选中、移入状态 项目背景&#xff1a;郑州院XX项目首页-新闻展示模块&#xff0c;鼠标移入显示对应图片&#xff0c;且体现选中和移入状态 首次加载&#xff1a; 切换列表后&#xff1a; html: <el-row :gutter"20"…

k8s系列之十五 Istio 部署Bookinfo 应用

Bookinfo 应用中的几个微服务是由不同的语言编写的。 这些服务对 Istio 并无依赖&#xff0c;但是构成了一个有代表性的服务网格的例子&#xff1a;它由多个服务、多个语言构成&#xff0c;并且 reviews 服务具有多个版本。 该应用由四个单独的微服务构成。 这个应用模仿在线书…

javaSwing日记管理系统

一、简介 使用 Java Swing 开发日记管理系统 在今天的博客中&#xff0c;我将向您介绍如何使用 Java Swing 开发一个简单而功能强大的日记管理系统。这个系统将具有登录、注册、找回密码、写日志以及切换主题等功能。我们将使用 MySQL 数据库来存储用户信息和日记内容。 二、…

Springboot集成shiro框架

前言 以前的项目代码&#xff0c;整理记录一下。 一、什么是shiro 官方&#xff1a;Shiro是一个功能强大且易于使用的Java安全框架&#xff0c;可以运行在JavaSE和JavaEE项目中&#xff0c;可执行身份验证、授权、加密和会话管理。 二、Shiro核心组件 1、UsernamePasswordT…

面试真经(运维工程师)

1.熟悉的排序算法有哪些&#xff0c;它们的时间空间复杂度如何? 排序算法主要分为内部排序和外部排序。内部排序指的是数据记录在内存中进行排序&#xff0c;而外部排序则适用于排序的数据量很大&#xff0c;一次不能容纳全部排序记录的情况&#xff0c;需要在排序过程中访问…

【爬虫】专栏文章索引

为了方便 快速定位 和 便于文章间的相互引用等 作为一个快速准确的导航工具 爬虫 目录&#xff1a; &#xff08;一&#xff09;web自动化和接口自动化 &#xff08;二&#xff09;实战-爬取Boss直聘信息数据

为什么物联网网关需要边缘计算能力?边缘计算应用场景有哪些?

【前言】本篇为物联网硬件系列学习笔记&#xff0c;分享学习&#xff0c;欢迎评论区交流~ 什么是边缘计算&#xff1f; 边缘计算&#xff08;Edge Computing&#xff09;是一种分布式计算范式&#xff0c;旨在将计算和数据存储功能放置在接近数据源或终端设备的边缘位置&#…

一代大神跌落神坛——Java炸了!

曾经它是只手遮天的一大计算机语言.......可现如今&#xff0c;腹背受敌、大势已去&#xff0c;一代神话跌落神坛&#xff01; Java薪水20k降至15k难掩颓势&#xff0c;事业编3k升至3500尽显嫡道风范&#xff01;嫡嫡道道、嫡嫡道道~ 没错&#xff0c;就是它&#xff01;Java…