美文网首页
实战·基于客户端存储的可离线使用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