todo_list开发笔记
todo_list开发笔记
Preface
在大学的最后的一个寒假(考上研另说)里重新复习一下前端三件套做的练手Demo,在大致过了一遍《Javascript高级程序设计第三版》之后总感觉和之前读的时候感觉差不多,寒假这次不记得是第几次看了,断断续续没看完的状态。寒假这次重新学的高程三大概过了一下日常开发所要使用的东西,对于闭包、作用域链之类的还没看打算开学再搞。在这次的高程三学习中对于DOM的理解简直是全新体验,以前一直是把DOM看成是getElementById之类的操作,没有理解到DOM的核心思想是将HTML结点看做对象调用方法,将结点当做对象来使用(这点我直接震惊我对DOM的是什么勾八理解)。
这次做的todoList Demo完全使用HTML、CSS、Javascript原生DOM完成。虽然是个简单的东西,但是在做的时候也遇到了很多逻辑上的东西以及一些技术问题。大致来说完成了一个小目标吧。话不多说上才艺
Github项目地址 :https://github.com/JYThomas/toDoList_Demo
一、Demo预览
二、遇到的技术问题及解决方法
这里将从HTML、CSS、Javascript三方面遇到的问题分类讲起
(一)、HTML
这方面遇到的问题比较少,基本上就是页面结构。要注意的是外部文件的引入
1.引入外部CSS文件
1 |
|
2.引入外部JS文件:这里需要特别注意遇到一个问题就是外部JS文件引入的位置应该是位于body标签内部,所有的页面元素后面。刚刚开始放的位置是head标签里面,但是后面在调用JS文件的时候发现函数老是报错,原因文件从上到下编译,JS文件放在head里面的时候 涉及了DOM操作 ,但是这个时候body里面的页面元素还没有渲染完成,所以获取到的变量时undefined,放在body标签内部,所有的页面元素后面就解决了这个问题。
1 |
|
(二)、CSS
使用div的时候为其添加
height
、width
属性才看得到盒子。盒子元素背景是background-color,color的话是div里面的文字元素的颜色。类 和 id 的css分别是 ‘.’ 和 ‘#’
1
2
3
4
5
6
7
8
9.mainContent {
width: 700px;
height: auto;
margin: 0 auto;
padding-top: 10px ;
padding-bottom: 10px ;
border-radius: 20px;
background-color: aquamarine;
}1
2
3
4
5
6
7#addTodoArea{
width: 600px;
height: 200px;
margin: 0 auto;
border-radius: 20px;
background-color: #FFCC99;
}设置某个元素下元素A的样式
1
2
3
4
5
6li下className为delBtn的元素
li .delBtn{
float: right;
border-radius: 3px;
background-color: #FFB6C1;
}
文字居中、垂直居中、浮动
1
2
3
4
5
6
7#Heading{
width: 200px;
height: 80px;
margin: 5px auto;
text-align: center; //文字居中
line-height: 80px; //垂直居中与height等值
}
随页面调整大小
1
2
3
4.mainContent {
width: 700px;
height: auto; //高度自动调整
}margin 与 padding
margin是指从自身边框到另一个容器边框之间的距离,就是容器外距离。(外边距)
padding是指自身边框到自身内部另一个容器边框之间的距离,就是容器内距离。(内边距)
调整div里面的其他元素位置用padding,调整div外部盒子与盒子位置关系用margin
(三)、Javascript
全局变量:直接在文档外部定义变量
1
2
3
4
5
6var toDoArr = new Array(); //创建全局动态数组
var btn = document.getElementById("add");
var tbx = document.getElementById("input");
var toDo_Ol = document.querySelectorAll("ol")[0]; //获取代办列表
var finished_Ol = document.querySelectorAll("ol")[1]; //获取已完成列表
var cleanBtn = document.getElementById("cleanBtn");ES6局部变量声明:let
1
2
3
4btn.onclick = function(){
let tbxVal = tbx.value;
....
}返回字符串某个字符前的字符串
1
2
3
4
5// 过滤li的文字,过滤返回特定字符'<'前的文字
function filter(str){
let res = str.split('<')[0];
return res;
}DOM动态结点生成appendChild 及 删除removeChild
思想是将小的结点挂载到大的结点上 大结点.appendChild(小结点);大结点.removeChild(小结点);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26// 创建列表结点
function createDataLi(_textVal){
let node = document.createElement("li"); //创建li结点
let finishedBtn = document.createElement("button");
let deleteBtn = document.createElement("button");
let textNode_toDo = document.createTextNode(_textVal); //创建text结点
let textNode_finished = document.createTextNode("finished");
let textNode_del = document.createTextNode("delete");
// 添加结点
finishedBtn.appendChild(textNode_finished);
deleteBtn.appendChild(textNode_del);
// 设置样式
finishedBtn.className = "finishedBtn";
deleteBtn.className = "delBtn";
// 添加结点到li
node.appendChild(textNode_toDo);
node.appendChild(deleteBtn);
node.appendChild(finishedBtn);
// 添加结点到ol
toDo_Ol.appendChild(node);
}
localStorage的使用(增、查)
1
2
3
4
5
6
7
8
9
10
11
12
13//数据存入localStorage
function setData(_toDoArr){
/*
只添加一组key-value实现localStorage数据存储覆盖问题
而不是使用多组key-value
*/
localStorage.setItem("todo",JSON.stringify(_toDoArr));
}
//获取localStorage字符串数据并返回
function getData(){
return localStorage.getItem("todo");
} localStorage的key与value不是每个一个数据都用一个键值对,而是只用一个键值对,在代码里面使用JSON.stringify()将对象转为字符串、JSON.parse()将字符串转为对象然后操作对象,避免操作字符串。
三、逻辑问题
数据存储:使用localStorage实现本地存储,页面关闭上次使用仍然存在。将数据获取到之后存放到localStorage存储,然后再从localStorage中获取数据渲染。以localStorage为中介,任何数据存储以及显示都要以localStorage中的数据为准。
添加待办:先将待办事项获取到然后存放到localStorage,之后删除页面上的DOM结点,再从localStorage中获取数据,生成结点渲染到页面上,解决li结点重复显示的问题
持续数据:当每次关闭或者操作页面的时候都要先从localStorage中获取数据存放到全局变量对象数组中,防止页面刷新或者关闭之后localStorage中的数据被重置
结点渲染函数load:在页面每次生成的时候执行load函数加载节点、渲染数据
函数封装的思想 :最大的体会就是每个函数做好自己的事,代码之间的逻辑通过函数的封装提高了程序的可读性,避免在程序流中出现过多高耦合的代码。
数据存储:使用localStorage一对键值对,存储的时候存储的是字符串,在操作数据的时候将字符串转换为对象数组对数据进行访问。
使用事件委托处理列表点击事件减少DOM操作稍微提高程序性能。
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!