接上回
默认大家都以及有了充分的知识储备,我们就准备真正的动手开始制作我们的小应用。
在这里我提前定义好后边的代码会引用到的变量
const settingForm = document.forms.settings,
searchForm = document.forms.search,
nav = document.querySelector('ul'),
addForm = document.forms.add,
// 通过hash值映射到tabIndex
hashToIndex = {
'#list': 0,
'#add': 1,
'#settings': 2
},
// 判断localStorage是否可用
localStorageAvailable = ('localStorage' in window),
indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.msIndexedDB || false,
IDBKeyRange = window.IDBKeyRange || window.webkitIDKeyRange || window.mozIDKeyRange || window.msIDKeyRange || false,
// webSQL对象并未实现为window成员,可以侦察window成员的openDatabase是否存在以检测web sql
webSQLSupport = ('openDatabase' in window)
let db = null
创建HTML文档结构
这是相对简单的部分,但是值得注意的是!
<a>
标签中的链接都是形如 #AAA
形式,该方法不会触发网页重载,而是再url后添加#
——hash值,可通过location.hash
获取。
location.hash
改变时,会监听到hashchange
事件,配合js完成路由的跳转,这也是目前流行框架中前端路由实现的方法之一。
location.hash详解
<body class="list">
<header>
<h1><span id="user_name">My</span>  Tasks</h1>
<nav>
<ul>
<li class="active">
<a href="#list" class="list">任务列表</a>
</li>
<li>
<a href="#add" class="add">添加任务</a>
</li>
<li>
<a href="#settings" class="settings">设置</a>
</li>
</ul>
</nav>
</header>
<section class="list">
<form name="search" class="search_form">
<input type="text" name="query" placeholder="搜索任务">
<input type="submit" value="搜索">
</form>
<ul id="task_list"></ul>
</section>
<section class="add">
<form name="add" class="add_form">
<h3 class="task_desc">
任务描述
</h3>
<textarea name="desc" class="task_desc_input" placeholder="请输入任务描述"></textarea>
<h3 class="task_due_date">完成日期</h3>
<input type="date" name="due_date" class="task_due_date_input">
<input type="submit" value="添加一个新任务" class="add_button">
</form>
</section>
<section class="settings">
<form name="settings" class="setting_form">
<div class="setting_form_div">
<h3>姓名</h3>
<input type="text" name="name" class="name">
<h3 class="color_scheme">颜色</h3>
<select name="color_scheme" class="scheme">
<option value="white">白色</option>
<option value="black">黑色</option>
</select>
<input type="submit" value="保存设置" class="button save_setting">
<input type="reset" value="重置所有数据" class="button reset">
</div>
</form>
</section>
</body>
利用css控制视图可见性
在监听到hashchange
事件后,js需要做出响应,将对应的hash值匹配到对应的视图,从而实现每次只显示一个视图的效果,并且实现根据不同hash值显示不同视图。
只有<body>
标签的class
值与<section>
标签的class
值相同时对应的<section>
元素才会显示。从而,js代码中,只需要控制body
标签的class
值,便可以实现视图切换的效果
css代码
section{
display: none
}
body.list section.list,
body.add section.add,
body.settings section.settings{
display: block
}
js代码
let jump = () => {
changeActive(location.hash) //控制nav的active
switch(location.hash) {
case '#add':
document.body.className = 'add'
break
case '#settings':
document.body.className = 'settings'
break
default:
document.body.className = 'list'
}
}
window.addEventListener('hashchange', jump, false)
到现在,我们以及实现了nav的功能,以及网页的整体架构。
丑陋的css代码就不贴出来了 呜呜呜
接下来,我们开始动手制作相对简单的部分——保存用户基本设置。
利用Web Storage管理数据
我们使用了web Storage的api实现数据存储的功能
其中,web Storage在window中定义了两个属性
- localStorage
- sessionStorage
前者可以永久保持在客户端中,只有手动清除时才会生效,后者在浏览器关闭时数据就会立刻丢失
在本应用中,使用localStorage存储用户名与用户选择主题,在进入应用时,读取存储数据。是不是so easy!
两个常用的api
localStorage.getItem() // 存储数据, 接受两个参数第一个参数为键名,用于之后获取值,第二个参数为值。
localStorage.setItem() // 获取数据,接受一个键名作为参数,返回键对应的值
加载用户设置
const localStorageAvailable = ('localStorage' in window) // 确认浏览器是否支持localStorage
let loadingSetting = () => {
if (localStorageAvailable) {
// 从localStorage中获取值
let name = localStorage.getItem('name'),
colorScheme = localStorage.getItem('colorScheme'),
nameDisplay = document.querySelector('#user_name'),
title = document.querySelector('h1')
nameFiled = settingForm.name
if (name) {
nameDisplay.innerHTML = name + "'s"
nameFiled.value = name
} else {
nameDisplay.innerHTML = "My"
nameFiled.value = ''
}
if (colorScheme) {
title.className = colorScheme
} else {
title.className = 'white'
}
}
}
loadingSetting()
保存用户设置
let saveSettings = (e) => {
// 阻止默认事件发生
e.preventDefault()
if (localStorageAvailable) {
let name = settingForm.name.value
if (name.length > 0) {
var colorScheme = settingForm.color_scheme.value
localStorage.setItem('name', name)
localStorage.setItem('colorScheme', colorScheme)
loadingSetting()
location.hash = "#list"
}
}
}
settingForm.addEventListener('submit', saveSettings, false) // 为submit按钮添加事件监听程序
删除所有用户设置
let resetSetting = (e) => {
e.preventDefault()
if (confirm('您确定清除所有用户设置?', '确定')) {
if (localStorageAvailable) {
localStorage.clear()
dropDatabase() // 删除数据库中的所有数据,以后会调用
}
loadingSetting()
location.hash = "#list"
}
}
目前,我们已经实现了用户设置界面的全部功能,开森!
未完....
网友评论