今日待办案例

216 阅读1分钟
1.模拟任务数据
2.实现任务列表的动态渲染
3.实现任务的新增
4.实现任务状态的更新,同时改变任务项的样式
5.能够统计任务数量
6.能够实现任务的删除
7.能够实现任务的清理
8.完成任务的持久化,本地存储

<body>
  <div id="app">
    <div class="box">
      <h1>待办列表</h1>
      <div class="tool">
        <input autofocus="" class="userTask" type="text" placeholder="请输入代办事项" />
      </div>
      <ul class="center">
        <!-- <li class="">
          <div>
            <input class="ck" type="checkbox" /><span class="false">写1000代码</span>
          </div>
          <button class="del">X</button>
        </li>
        <li class="finished">
          <div>
            <input class="ck" type="checkbox" checked="" /><span class="false">调100个bug</span>
          </div>
          <button class="del">X</button>
        </li>
        <li class="">
          <div>
            <input class="ck" type="checkbox" /><span class="false">解决组员的10个问题</span>
          </div>
          <button class="del">X</button>
        </li> -->
      </ul>
      <section>
        <span> <b class="num1">0</b> 未完成</span><a href="#">清理 <b class="num2">0</b> 已完成</a>
      </section>
    </div>
  </div>

  <script>
    //入口函数
    window.addEventListener('load', function () {

      //模拟数据  模拟的状态值是真的还是假的都无所谓
      // let arr = [
      //   { id: 1, state: true, value: '听歌' },
      //   { id: 2, state: true, value: '吃饭' }
      // ]

      //获取元素
      let center = document.querySelector('.center') // 静态结构页面内容
      let userTask = document.querySelector('.userTask')  // 文本输入框
      let num1 = document.querySelector('.num1')  // 未完成数量
      let num2 = document.querySelector('.num2')  // 已完成数量
      let add = document.querySelector('section a')  // 清除已完成按钮

      //获取本地存储
      let arr = JSON.parse(localStorage.getItem('offic_88')) || []  //  []防止数据为空时会报错


      function init() {
        //一.数据渲染 = 静态结构 + 数据
        //1.创建一个空的字符串,以便后面拼接数据内容
        let newStr = ''
        //2.遍历js后端数据内容(改数据内容)   
        //finished为css原有的删除线样式类名 state状态值是true和false是布尔值所以写v.state自动判断即可
        //js是转换为bool成为false的有: 0 '' "" null undefined NaN
        arr.forEach(function (v, i) {
          newStr += `
        <li class="${v.state ? 'finished' : ''}">
          <div>
            <input class="ck" type="checkbox"  ${v.state ? 'checked' : ''}   data-id="${v.id}"/><span class="text">${v.value}</span>
          </div>
          <button class="del" data-id="${v.id}">X</button>
        </li>
      `
        })
        //3.把生成的数据内容,赋值到元素页面里面去
        center.innerHTML = newStr

      }
      init()  //渲染

      //按下回车键,执行数据渲染
      window.addEventListener('keydown', function (e) {
        if (e.which == 13 && userTask.value.trim().length !== 0) { //要同时满足按下的是回车键和输入框内容长度不为0

          //二.数据的增加
          //1.把你需要新增的数据,生成一个新的对象
          let obj = {
            //追加的数据都是在最后面追加的,所有id号应该是现有的最后一个id号+1
            id: arr.length > 0 ? arr[arr.length - 1].id + 1 : 1,  //当页面元素为0的时候,id号为1        
            state: false,
            value: userTask.value
          }
          //2.把生成的新对象追加到数组
          arr.push(obj)

          init()  //渲染
          save() //本地存储
          num()  //总数
          userTask.value = null //按下回车键时,清空文本输入框的页面内容
        }

      })

      //三.数据的删除--动态渲染的元素,用事件委托
      center.addEventListener('click', function (e) {  //给父元素绑定单击事件
        if (e.target.className == 'del') {   //判断当前用户单击的是否为删除按钮
          //获取当前你想删除的数据的id
          let id = e.target.dataset.id  //dataset获取到自定义属性的一个对象
          // console.log(id);
          arr = arr.filter(function (v, i) {  // filter筛选过滤数组
            return id != v.id   //返回没被删除掉的新数组
          })
          init()  //渲染
          save() //本地存储
          num()  //总数
        }
      })


      //四.复选框操作  状态取反
      //1.利用事件委托给父元素绑定单击事件 跟删除一样拿id号
      center.addEventListener('click', function (e) {
        if (e.target.className == 'ck') {  // 判断用户当前点击的是否为复选框按钮
          let id = e.target.dataset.id  //dataset获取到自定义属性的一个对象
          arr.forEach(function (v, i) {
            if (id == v.id) {
              //修改数据本身
              v.state = !v.state  //选相反状态,若为选中则变为不选中,反之亦然
              init()  //渲染
              save() //本地存储
              num()  //总数
            }
          })

        }
      })


      //五.统计已完成和未完成  为封装起来,以便删除、增加等操作调用
      function num() {
        let count = 0  //声明一个总数
        arr.forEach(function (v, i) {
          //统计未完成任务的数量
          if (!v.state) {
            count++
          }
          //把未完成任务的数量渲染到页面
          num1.innerHTML = count
          //把已完成任务的数量渲染到页面
          num2.innerHTML = arr.length - count

        })
      }
      num()

      // 六.清除已完成按钮(所谓清理就是将数据属性state为true的值删除)
      add.addEventListener('click', function () {
        arr = arr.filter(function (v, i) {
          //清理已完成,保留stare为false的数据
          return !v.state
        })
        init()  //渲染
        save() //本地存储
        num() //总数

      })


      // 七.封装一个本地存储,以便调用  记得把后台原始数据注释起来(即模拟数据)
      function save() {
        localStorage.setItem('offic_88', JSON.stringify(arr))
      }


    })



  </script>
</body>