美文网首页
实战·基于客户端存储的可离线使用web应用——myTasks(2

实战·基于客户端存储的可离线使用web应用——myTasks(2

作者: hux1ao | 来源:发表于2018-02-02 14:58 被阅读0次

接上回

默认大家都以及有了充分的知识储备,我们就准备真正的动手开始制作我们的小应用。

在这里我提前定义好后边的代码会引用到的变量

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> &nbspTasks</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"
      }
    }

目前,我们已经实现了用户设置界面的全部功能,开森!
未完....

相关文章

网友评论

      本文标题:实战·基于客户端存储的可离线使用web应用——myTasks(2

      本文链接:https://www.haomeiwen.com/subject/agqezxtx.html