原生js实现TodoMVC

2020-12-24 10:30

阅读:430

标签:move   inner   footer   技术   one   dom   ems   image   ble   

原生js实现TodoMVC

先用html和css写好页面的基本结构样式,代码如下,

index.html

DOCTYPE html>
html lang="en">
head>
  meta charset="UTF-8">
  title>Documenttitle>
  link rel="stylesheet" href="./index.css">
head>
body>
  section id="app">
    header>
      h2>ToDoMVCh2>
      input type="text" id="new-todo" class="box" placeholder="What needs to be done?">
    header>
    section>
      div id="todo">
        ul>ul>
        div class="box card hideCard">
          span>span>
          input type="radio" name="btn" id="all" checked>
          input type="radio" name="btn" id="active">
          input type="radio" name="btn" id="completed">
          label for="all">alllabel>
          label for="active">activelabel>
          label for="completed">completedlabel>
        div>
      div>
    section>
    footer>
      div>
        by chenguang123
      div>
    footer>
  section>
body>
html>

index.css

* {
  margin: 0;
  padding: 0;
}

html, body {
  height: 100%;
}

#app {
  width: 900px;
  min-height: 100%;
  background-color: rgb(237, 237, 237);
  margin: auto;
  overflow: hidden;
}

header h2 {
  margin: 20px auto;
  text-align: center;
  font-size: 32px;
  color: gray;
}

#new-todo {
  border: none;
  outline: none;
}

.box {
  position: relative;
  box-sizing: border-box;
  display: block;
  width: 500px;
  height: 50px;
  padding: 10px 20px;
  box-shadow: .5px .5px 3px rgb(132, 132, 132);
  font-size: 24px;
  margin: auto;
}

.box input {
  width: 15px;
  height: 15px;
  margin: 0 10px;
}

.list button {
  position: absolute;
  right: 20px;
  visibility: hidden;
  border: none;
  outline: none;
  background-color: transparent;
  font-size: 24px;
  cursor: pointer;
  color: rgb(161, 161, 161);
  transition: color .5s linear;
}

.list:hover button {
  visibility: visible;
}

.list button:hover {
  color: gray;
}

.card {
  font-size: 16px;
}

.card span {
  margin-right: 30px;
}

.card input {
  display: none;
}

.card label {
  border: 1px solid transparent;
  margin: 5px;
  cursor: pointer;
  transition: border .3s linear;
}

.card label:hover {
  border: 1px solid black;
}

.card input:nth-of-type(1):checked ~ label:nth-of-type(1) {
  border: 1px solid black;
}
.card input:nth-of-type(2):checked ~ label:nth-of-type(2) {
  border: 1px solid black;
}
.card input:nth-of-type(3):checked ~ label:nth-of-type(3) {
  border: 1px solid black;
}

footer {
  margin: 30px;
  text-align: center;
  color: gray;
}

.check {
  text-decoration: line-through;
  color: gray;
}

.d1 {
  display: none;
}
.d2 { display: none; } .hideCard { visibility: hidden; } .showCard { visibility: visible; }

 

此时页面展示如下,

技术图片

 

接下来编写index.js,实现TodoMVC的功能,把该文件引入到index.html文件中

// 添加任务到ul中
var ul = document.querySelector(‘#todo ul‘)

// 添加任务的输入框
var newTodo = document.querySelector(‘#new-todo‘)

// 底部用来显示状态的元素
var card = document.querySelector(‘.card‘)

// 用来显示任务数的元素
var span = document.querySelector(‘.card span‘)

// 全部的任务
var all = document.querySelector(‘#all‘)

// 正在进行的任务
var active = document.querySelector(‘#active‘)

// 完成的任务
var completed = document.querySelector(‘#completed‘)

var app = {
  arrList: [], // 保存所有任务
  count: 0, // 任务数
  init: function () {
    // 监听输入框,添加要做的任务
    newTodo.onkeyup = function (e) {
      if (e.keyCode == 13) {
        if (newTodo.value !== ‘‘) {
          this.addList(newTodo.value)
          newTodo.value = ‘‘
          card.classList.replace(‘hideCard‘, ‘showCard‘)
          span.innerHTML = this.count + ‘ items left‘
          if (all.checked) {
            this.showAll()
          }
          if (active.checked) {
            this.showActive()
          }
          if (completed.checked) {
            this.showCompleted()
          }
        }
      }
    }.bind(this)

    // 监听任务被删除、完成、未完成
    ul.onclick = function (e) {
      this.change(e)
      if (all.checked) {
        this.showAll()
      }
      if (active.checked) {
        this.showActive()
      }
      if (completed.checked) {
        this.showCompleted()
      }
    }.bind(this)

    all.onclick = function () {
      this.showAll()
    }.bind(this)

    active.onclick = function () {
      this.showActive()
    }.bind(this)

    completed.onclick = function () {
      this.showCompleted()
    }.bind(this)
  },
  change: function (e) {
    if (e.target.localName === ‘button‘) {
      var i = this.arrList.indexOf(e.target.parentNode)
      // 若点击button要删除的任务是未完成的,则count数也要减一
      if (!e.target.parentNode.children[0].checked) {
        this.count--
        span.innerHTML = this.count + ‘ items left‘
      }
      this.arrList.splice(i, 1)
      e.target.parentNode.parentNode.removeChild(e.target.parentNode)
      if (this.arrList.length === 0) {
        card.classList.replace(‘showCard‘, ‘hideCard‘)
      }
    } else if (e.target.localName === ‘input‘) {
      // 若点击的是input,则判断任务是否完成
      if (e.target.checked) {
        e.target.parentNode.classList.add(‘check‘)
        e.target.parentNode.classList.replace(‘a‘, ‘b‘)
        this.count--
        span.innerHTML = this.count + ‘ items left‘
      } else {
        e.target.parentNode.classList.remove(‘check‘)
        e.target.parentNode.classList.replace(‘b‘, ‘a‘)
        this.count++
        span.innerHTML = this.count + ‘ items left‘
      }
    }
  },
  addList: function (val) {
    var li = document.createElement(‘li‘)
    li.classList.add(‘box‘)
    li.classList.add(‘list‘)
    li.classList.add(‘a‘)
    var content = `
                ${val}
        
      `
    li.innerHTML = content
    this.arrList.push(li)
    ul.appendChild(li)
    this.count++
  },
  /* 
    类a代表未完成的任务
    类b代表已完成的任务
    类d2代表隐藏未完成的任务
    类d1代表隐藏已完成的任务
    
    addList函数中,给新的任务添加了一个类a;change函数中,当被选中后把类a换成了类b
    
    showActive函数中,要显示未完成的任务,所以要把已完成的任务隐藏,把带有类b的任务,换成了类d1,该类为display: none
    该函数中除了要隐藏已完成任务,也要将被隐藏的未完成任务显示出来,把类d2换成类a

    showCompleted函数中,要显示已完成的任务,所以要把未完成的任务隐藏,把带有类a的任务,换成了类d2,该类为display: none
    该函数中除了要隐藏未完成任务,也要将被隐藏的未完成任务显示出来,把类d1换成类b

  */
  showAll: function () {
    for (let i = 0; i this.arrList.length; i++) {
      this.arrList[i].classList.replace(‘d1‘, ‘b‘)
      this.arrList[i].classList.replace(‘d2‘, ‘a‘)
    }
  },
  showActive: function () {
    for (let i = 0; i this.arrList.length; i++) {
      this.arrList[i].classList.replace(‘d2‘, ‘a‘)
      this.arrList[i].classList.replace(‘b‘, ‘d1‘)
    }
  },
  showCompleted: function () {
    for (let i = 0; i this.arrList.length; i++) {
      this.arrList[i].classList.replace(‘d1‘, ‘b‘)
      this.arrList[i].classList.replace(‘a‘, ‘d2‘)
    }
  }
}

app.init()

 

最后实现的效果如下,

技术图片

 

技术图片

 技术图片

 

原生js实现TodoMVC

标签:move   inner   footer   技术   one   dom   ems   image   ble   

原文地址:https://www.cnblogs.com/chenguang123/p/13943840.html


评论


亲,登录后才可以留言!