客户端保存数据
采用 JavaScript 代码的简单 HTML 页面可以作为实现一些小应用的很好的途径。可以采用小的帮助程序来自动化一些基本的任务。通过关联一些表单字段和事件处理器,你可以实现华氏度与摄氏度的转换。也可以实现由主密码和网站名来生成密码等各种任务。
当一个应用需要存储一些东西以便于跨对话使用时,则不能使用 JavaScript 绑定因为每当页面关闭时这些值就会丢失。你可以搭建一个服务器,连接到因特网,将一些服务数据存储到其中。在第20章中将会介绍如何实现这些,当然这需要很多的工作,也有一定的复杂度。有时只要将数据存储在浏览器中即可。
localStorage
对象可以用于保存数据,它在页面重新加载后还存在。这个对象允许你将字符串存储在某个名字(也是字符串)下,下面是具体示例。
localStorage.setItem("username", "marijn");
console.log(localStorage.getItem("username"));
// → marijn
localStorage.removeItem("username");
一个在localStorage
中的值会保留到其被重写时,它也可以通过removeItem
来清除,或者由用户清除本地数据。
不同字段名的站点的数据会存在不同的地方。这也表明原则上由localStorage
存储的数据只可以由相同站点的脚本编辑。
浏览器的确限制一个站点可以存储的localStorage
的数据大小。这种限制,以及用垃圾填满人们的硬盘并不是真正有利可图的事实,防止该特性占用太多空间。
下面的代码实现了一个粗糙的笔记应用。程序将用户的笔记保存为一个对象,将笔记的标题和内容字符串相关联。对象被编码为 JSON 格式并存储在localStorage
中。用户可以从<select>
选择字段中选择笔记并在<textarea>
中编辑笔记,并可以通过点击一个按钮来添加笔记。
Notes: <select></select> <button>Add</button><br>
<textarea style="width: 100%"></textarea>
<script>
let list = document.querySelector("select");
let note = document.querySelector("textarea");
let state;
function setState(newState) {
list.textContent = "";
for (let name of Object.keys(newState.notes)) {
let option = document.createElement("option");
option.textContent = name;
if (newState.selected == name) option.selected = true;
list.appendChild(option);
}
note.value = newState.notes[newState.selected];
localStorage.setItem("Notes", JSON.stringify(newState));
state = newState;
}
setState(JSON.parse(localStorage.getItem("Notes")) || {
notes: {"shopping list": "Carrots\nRaisins"},
selected: "shopping list"
});
}
list.addEventListener("change", () => {
setState({notes: state.notes, selected: list.value});
});
note.addEventListener("change", () => {
setState({
notes: Object.assign({}, state.notes,
{[state.selected]: note.value}),
selected: state.selected
});
});
document.querySelector("button")
.addEventListener("click", () => {
let name = prompt("Note name");
if (name) setState({
notes: Object.assign({}, state.notes, {[name]: ""}),
selected: name
});
});
</script>
脚本从存储在localStorage
中的"Notes"
值来获取它的初始状态,如果其中没有值,它会创建示例状态,仅仅带有一个购物列表。从localStorage
中读取不存在的字段会返回null
。
setState
方法确保 DOM 显示给定的状态,并将新状态存储到localStorage
。 事件处理器调用这个函数来移动到一个新状态。
在这个例子中使用Object.assign
,是为了创建一个新的对象,它是旧的state.notes
的一个克隆,但是添加或覆盖了一个属性。 Object.assign
选取第一个参数,向其添加所有更多参数的所有属性。 因此,向它提供一个空对象会使它填充一个新对象。 第三个参数中的方括号表示法,用于创建名称基于某个动态值的属性。
还有另一个和localStorage
很相似的对象叫作sessionStorage
。这两个对象之间的区别在于sessionStorage
的内容会在每次会话结束时丢失,而对于多数浏览器来说,会话会在浏览器关闭时结束。