引言
想象一下,当你再次访问一个购物网站时,它竟然还记得你上次浏览的商品!这背后其实藏着一位默默工作的“贴心小秘书”——localStorage。今天,咱们就来揭开它的神秘面纱,并且通过一个更加复杂的例子来了解它是如何工作的。在这个信息爆炸的时代,能有这么一位记忆力超群的小秘书帮我们记住网页的状态,简直不要太幸福!
这次我们要实现的页面如下:
HTML5 特性介绍
首先,我们先来看看在这个HTML文件中用到了哪些HTML5特性:
- 文档类型声明
<!DOCTYPE html>:这是告诉浏览器,“嘿,我是HTML5家族的一员哦!”别小看这一行代码,它就像是给浏览器发了一张名片,确保大家都能愉快地交流。 - 视口设置
<meta data-n-head="ssr" name="viewport" content="width=device-width, initial-scale=1, user-scalable=no, viewport-fit=cover">:这个标签不仅确保页面在各种设备上都能有良好的视觉效果,还特别指定了用户不能缩放页面,以提供更一致的用户体验。就像给移动设备写的一封信,说:“请把我显示得好看一点,别让我变形了。” - 表单增强功能:例如
placeholder(输入框里的提示文字)和required(规定必须填写),这些都让用户的体验更加友好,就像有个人在旁边轻声提醒:“这里要填哦”。这样的设计不仅提高了用户交互的效率,还增加了网页的人情味。
代码解析
接下来,让我们用中文口语化地解析这段代码的工作原理以及如何使用localStorage保存数据。以下是完整的HTML和JavaScript代码示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta data-n-head="ssr" name="viewport" content="width=device-width, initial-scale=1, user-scalable=no, viewport-fit=cover">
<title>LocalStorage</title>
<style>
* {
margin: 0;
padding: 0;
}
html {
box-sizing: border-box;
background: url('http://wes.io/hx9M/oh-la-la.jpg') center no-repeat;
background-size: cover;
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
font-family: Futura,"Trebuchet MS",Arial,sans-serif;
}
*, *:before, *:after {
box-sizing: inherit;
}
svg {
fill:white;
background: rgba(0,0,0,0.1);
padding: 20px;
border-radius: 50%;
width: 200px;
margin-bottom: 50px;
}
.wrapper {
padding: 20px;
max-width: 350px;
background: rgba(255,255,255,0.95);
box-shadow: 0 0 0 10px rgba(0,0,0,0.1);
}
h2 {
text-align: center;
margin: 0;
font-weight: 200;
}
.plates {
margin: 0;
padding: 0;
text-align: left;
list-style: none;
}
.plates li {
border-bottom: 1px solid rgba(0,0,0,0.2);
padding: 10px 0;
font-weight: 100;
display: flex;
}
.plates label {
flex: 1;
cursor: pointer;
}
.plates input {
display: none;
}
.plates input + label:before {
content: '⬜';
margin-right: 10px;
}
.plates input:checked + label:before {
content: '🌮';
}
.add-items {
margin-top: 20px;
}
.add-items input {
padding: 10px;
outline: 0;
border: 1px solid rgba(0,0,0,0.1);
}
</style>
</head>
<body>
<div class="wrapper">
<h2>LOCAL TAPAS</h2>
<p></p>
<ul class="plates">
<li>Loading Taps...</li>
</ul>
<form class="add-items">
<input type="text" name="item" placeholder="Item Name" required>
<input type="submit" value="+ Add Item">
</form>
<script>
const addItems = document.querySelector('.add-items'); // 获取表单元素
const itemsList = document.querySelector('.plates'); // 获取项目列表容器
let items = JSON.parse(localStorage.getItem("items")) || []; // 从localStorage读取数据,默认为空数组
function addItem(event) {
event.preventDefault(); // 阻止表单默认提交行为
const text = (this.querySelector('[name=item]')).value.trim(); // 获取并修剪用户输入文本
if (!text) return; // 如果输入为空,直接返回不做处理
// 创建新项对象
const item = {
text,
done: false
};
items.push(item); // 将新项添加到数组
populateList(items, itemsList); // 更新UI
localStorage.setItem('items', JSON.stringify(items)); // 更新localStorage
this.reset(); // 重置表单
}
function toggleDone(event) {
const index = event.target.getAttribute('data-index');
if (index !== null) {
items[index].done = !items[index].done;
localStorage.setItem('items', JSON.stringify(items));
populateList(items, itemsList);
}
}
function removeItem(event) {
const index = event.target.closest('li').getAttribute('data-index');
if (index !== null) {
items.splice(index, 1);
localStorage.setItem('items', JSON.stringify(items));
populateList(items, itemsList);
}
}
function populateList(plates, platesList) {
platesList.innerHTML = plates.map((plate, i) => {
return `
<li data-index="${i}">
<input
type="checkbox"
data-index="${i}"
id="item${i}"
${plate.done ? 'checked' : ''}
onchange="toggleDone(event)">
<label for="item${i}">${plate.text}</label>
<button onclick="removeItem(event)">Remove</button>
</li>
`;
}).join('');
}
addItems.addEventListener('submit', addItem);
window.onload = () => {
populateList(items, itemsList); // 页面加载时渲染已有数据
};
</script>
</div>
</body>
</html>
解释
在这段代码里,我们创建了一个更复杂但同样直观的待办事项列表应用,用户可以像点菜一样添加新的小吃到列表中,并标记它们是否已经吃过了或者直接移除不想再吃的。所有的操作都会实时同步到localStorage,所以就算刷新页面,之前的选择也不会消失。
-
DOMContentLoaded事件:当整个HTML文档加载完成后触发,确保脚本在所有元素都准备好了之后才开始干活。这就像是等所有人都到齐了,才正式开饭,避免了有人还没到位就开始行动的尴尬。
-
loadItems函数:这个函数就像个勤快的小工,每次页面一加载就会跑去
localStorage里找有没有存过的东西,然后把它们展示出来。它负责的是确保你上次做的选择不会被遗忘,下次打开页面还能看到。 -
populateList函数:根据传入的数据生成对应的HTML结构,简单来说就是把数据变成你能看到的项目列表。它就像是厨房里的厨师,把食材变成了美味的菜肴,让你能够享受一顿丰盛的晚餐。
-
addItem函数:这里有个聪明的做法,它阻止了表单默认提交的行为,收集用户输入的新项,把它加到本地存储里,然后再更新界面,最后还帮用户清空了输入框,真贴心啊。这种做法不仅提高了效率,还让用户感觉特别好,好像有一个私人助手在帮你打理一切。
-
toggleDone函数:用来改变某个小吃的状态(比如我已经吃过啦)。每次做完这些动作,它还会记得更新一下
localStorage,好让下次打开页面时还能找到这些记录。这就好比是整理书架,把读过的书归类,保持书架的整洁有序。 -
removeItem函数:干脆把这个小吃从列表里踢出去。每当点击删除按钮时,它会查找对应的项目并将其从列表中移除,同时更新
localStorage中的记录,确保数据的一致性。
深入探讨
当然,localStorage不仅仅是用来保存一些简单的待办事项列表。实际上,它可以用于保存用户偏好、游戏进度、甚至临时文件等。但需要注意的是,localStorage并不是无限大的,每个域名下的存储空间大约为5MB左右。因此,在使用时应该合理规划,不要滥用。另外,由于localStorage中的数据是以字符串形式存储的,所以在存储复杂对象或数组时,需要使用JSON.stringify进行序列化,取出时再用JSON.parse反序列化。这有点像是把东西装进盒子里,再从盒子里拿出来,只不过这里的盒子是JSON格式的。
结语
通过这篇文章,希望你对localStorage有了更深入的理解,并且学会了如何利用它为自己的项目增添持久化存储的功能。记住,localStorage虽然是个好帮手,但也要注意别把敏感信息交给它保管哦。毕竟,谁都不希望自己的秘密被随便翻阅吧?
现在,轮到你动手试试看啦!如果你有任何问题或者想要分享你的创作,请随时留言评论。祝编程愉快,玩得开心!希望每一位读者都能成为自己网页的小秘书,打造独一无二的用户体验。