这次做得功能类似to do list,不过只有增加及改变状态的功能。
在开始之前我们需要先大致了解,本地的资料库也就是F12=>Application下的Storage。
Local storage(大小5-10M):
也是我们今天的重点,简而言之就是本地储存库,格式为 key : value
,只能记较单纯的资料类型,如数值、字串
,可以跨浏览器分页做使用
、使用者关掉分页或浏览器再打开资料仍不会消失
,且资料无期效限制,资料将永久被保留,除非我们手动作删除
。
cookie(大小约 4kb):
由于HTTP协定是无状态的概念
,所以Server处理完我们的资料就不会记得我们所做的纪录
、事情等,如我们在购物车购买东西,但是Server并不会知道我们买了什么,此时就需要cookie,而cookie是由Web server端产生
的,作为发送给browser端,而当browser接收到Cookie后,会将其中的key/value
,保存
到某个路径内的文本文件之中,让下次于造访同一网站时,就可以将Cookie自动发送给Web Server端
,像是local与server在交换时会带有的内容,会在验证、登入、购物车等情境下使用到
。
Session storage:
与session不同,session是存在server端
,Session storage存在本地端
,存在档案或资料库,搭配cookie使用
,生命週期较短,当使用者关掉浏览器或分页时,sessionStorage 中的资料将被清空
。
首先就是获取我们会用到的DOM元素,其中localStorage的资料获取需要透过getItem getItem(keyName);
,且获取的型态为字串
,所以要parse转为JSON型式([{},{}...])
,预设值为空阵列。
const addItems = document.querySelector('.add-items'); const itemsList = document.querySelector('.plates'); // 利用getItem获取localStorage中的资料 const items = JSON.parse(localStorage.getItem('items')) || [];
增添事件处理
// 送出增加列表事件 addItems.addEventListener('submit', addItem); // 点击列表状态切换事件 itemsList.addEventListener('click', toggleDone); createList(items, itemsList);
而增添事件的函数,是採submit触发,由于submit本身会有预设的动作
,如跳转到指定网址等,所以一开始需要加上e.preventDefault()来避免预设行为
,而后value是利用属性筛选器来获取(form底下有name="item"的DOM元素),
接着我们在将资料的值及状态(done)以物件型式储存。
而后push至我们的localStorage的资料阵列中,并利用setItem(setItem(keyName, keyValue);),来更新我们的localStorage资料
,且记得将我们已转为JSON型式的资料字串化
,因为要传回localStorage,而localStorage的资料都是以字串型式表示。
而这边还使用了一个清除在form下input中value的一个方法,HTMLFormElement.reset(),可清除表单内的资料
。
// 在表单输入资料并点击增加之处理 function addItem(e) { // 防止submit的预设行为(跳转页面...) e.preventDefault(); // let value = this.querySelector('input:first-child').value; let value = (this.querySelector('[name=item]')).value; const obj = { value, done: false }; // 将input输入之资料push进阵列(更新) items.push(obj); // 更新Local资料 localStorage.setItem( "items", // 记得将资料字串化 JSON.stringify(items) ); createList(items, itemsList); // 呼叫产生list(更新画面) // HTMLFormElement.reset() 可清除表单内的资料 this.reset(); // this.querySelector('[name=item]').value = ""; }
下面为产生列表的函数,记得最后要做join将 , 去除以空字串来隔开每笔资料。
// 第一个参数为资料,data=[]的用意,为赋予一个[]表示为预设值 // 第二个参数为我们要放置进去的DOM function createList(data = [], platesList) { // 将阵列中的物件拿出来处理 // 第一个参数为物件资料 // 第二个为下标 platesList.innerHTML = data.map((plate, index) => { return ` <li> <input type="checkbox" data-index=${index} id="item${index}" ${plate.done ? 'checked' : ''} /> <label for="item${index}">${plate.value}</label> </li> `; }).join(''); }
切换状态处理函数,由于target因为label的特性会触发两次,故我们利用matches来判断目标是否为input, (element.matches(selectorString); 可检查元素是否为指定选择器,是返回true,反之false
),来判断是否要继续执行,而后在对应的列表进行状态切换,最后别忘记更新我们的localStorage及画面。
function toggleDone(e) { console.log(e.target, e.currentTarget); // 发现target会重複触发 // 判断是否为Input,是的话才继续(避免会重複触发) if (!e.target.matches('input')) return; // skip this unless it's an input const el = e.target; // 自定义属性为data-index的DOM const index = el.dataset.index; // 切换其DOM的done状态 items[index].done = !items[index].done; // 更新local资料库 localStorage.setItem('items', JSON.stringify(items)); // 更新画面 createList(items, itemsList); }