• todolist案列——原生js


    目录

    实现目标:

    tidilist.html

    index.css

    index4.js

     过程:

    enter 按键监听事件存储数据

    存储数据saveDate()

    获取数据getDate()

    加载数据

    编辑数据

    删除数据

    切换正在进行和完成


    实现目标:

    • 文本框里输入内容,按下回车键生成待办事件
    • 点击待办事件复选框,可以把当前数据添加到已完成事件
    • 点击已完成事项复选框,是当前数据跳转回待办事件里面
    • 刷新页面内容不会丢失
    • 点击待办事件的a ,可删除待办事件
    • 点击待办事件表单,可以编辑保存修改后的数据

    tidilist.html

    1. html>
    2. <html>
    3. <head>
    4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    5. <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
    6. <title>ToDoList—最简单的待办事项列表title>
    7. <meta name="description" content="ToDoList无须注册即可使用,数据存储在用户浏览器的html5本地数据库里,是最简单最安全的待办事项列表应用!" />
    8. <link rel="stylesheet" href="index.css">
    9. head>
    10. <body>
    11. <header>
    12. <section>
    13. <form action="" id="form" onclick="">
    14. <label for="title">ToDoListlabel>
    15. <input type="text" id="title" name="title" placeholder="添加ToDo" required="required" autocomplete="off" />
    16. form>
    17. section>
    18. header>
    19. <section>
    20. <h2>正在进行 <span id="todocount">span>h2>
    21. <ol id="todolist" class="demo-box">
    22. ol>
    23. <h2>已经完成 <span id="donecount">span>h2>
    24. <ul id="donelist">
    25. ul>
    26. section>
    27. <footer>
    28. Copyright © 2014 todolist.cn <a href="javascript:clear();">cleara>
    29. footer>
    30. <script type="text/javascript" src="index4.js">script>
    31. body>
    32. html>

    index.css

    1. body {
    2. margin:0;
    3. padding:0;
    4. font-size:16px;
    5. background: #CDCDCD;
    6. }
    7. header {
    8. height:50px;
    9. background:#333;
    10. background:rgba(47,47,47,0.98);
    11. }
    12. section{
    13. margin:0 auto;
    14. }
    15. label{
    16. float:left;
    17. width:100px;
    18. line-height:50px;
    19. color:#DDD;
    20. font-size:24px;
    21. cursor:pointer;
    22. font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
    23. }
    24. header input{
    25. float:right;
    26. width:60%;
    27. height:24px;
    28. margin-top:12px;
    29. text-indent:10px;
    30. border-radius:5px;
    31. box-shadow: 0 1px 0 rgba(255,255,255,0.24), 0 1px 6px rgba(0,0,0,0.45) inset;
    32. border:none}
    33. input:focus{
    34. outline-width:0
    35. }
    36. h2{
    37. position:relative;
    38. }
    39. span{
    40. position:absolute;
    41. top:2px;
    42. right:5px;
    43. display:inline-block;
    44. padding:0 5px;
    45. height:20px;
    46. border-radius:20px;
    47. background:#E6E6FA;
    48. line-height:22px;
    49. text-align:center;
    50. color:#666;
    51. font-size:14px;
    52. }
    53. ol,ul{
    54. padding:0;
    55. list-style:none;
    56. }
    57. li input{
    58. position:absolute;
    59. top:2px;
    60. left:10px;
    61. width:22px;
    62. height:22px;
    63. cursor:pointer;
    64. }
    65. p{
    66. margin: 0;
    67. }
    68. li p input{
    69. top:3px;
    70. left:40px;
    71. width:70%;
    72. height:20px;
    73. line-height:14px;
    74. text-indent:5px;
    75. font-size:14px;
    76. }
    77. li{
    78. height:32px;
    79. line-height:32px;
    80. background: #fff;
    81. position:relative;
    82. margin-bottom: 10px;
    83. padding:0 45px;
    84. border-radius:3px;
    85. border-left: 5px solid #629A9C;
    86. box-shadow: 0 1px 2px rgba(0,0,0,0.07);
    87. }
    88. ol li{
    89. cursor:move;
    90. }
    91. ul li{
    92. border-left: 5px solid #999;
    93. opacity: 0.5;
    94. }
    95. li a{
    96. position:absolute;
    97. top:2px;right:5px;
    98. display:inline-block;
    99. width:14px;
    100. height:12px;
    101. border-radius:14px;
    102. border:6px double #FFF;
    103. background:#CCC;
    104. line-height:14px;
    105. text-align:center;
    106. color:#FFF;
    107. font-weight:bold;
    108. font-size:14px;
    109. cursor:pointer;
    110. }
    111. footer{
    112. color:#666;
    113. font-size:14px;
    114. text-align:center;
    115. }
    116. footer a{
    117. color:#666;
    118. text-decoration:none;
    119. color:#999;
    120. }
    121. @media screen and (max-device-width: 620px) {section{width:96%;padding:0 2%;}}
    122. @media screen and (min-width: 620px) {section{width:600px;padding:0 10px;}}

    index4.js

    1. var title = document.querySelector('#title') //表单
    2. var ol = document.querySelector('#todolist') //正在进行
    3. var ul = document.querySelector('#donelist') //已完成
    4. var todoCount = document.querySelector('#todocount')
    5. var doneCount = document.querySelector('#donecount')
    6. load()
    7. /* 回车存储数据 */
    8. title.addEventListener('keydown', function(e) {
    9. /* var e = window.event || e */
    10. var arr = getData() //在获取数据的基础上 拿到数组
    11. if (e.keyCode == 13) {
    12. var todo = {
    13. title: title.value,
    14. done: false
    15. }
    16. arr.push(todo)
    17. saveData(arr)
    18. var form = document.querySelector('#form') //让表单返回默认值
    19. form.reset()
    20. load()
    21. }
    22. })
    23. //获取数据
    24. function getData() {
    25. var data = window.localStorage.getItem('todo')
    26. if (data != null) {
    27. return JSON.parse(data)
    28. } else {
    29. return []
    30. }
    31. }
    32. //存储数据
    33. function saveData(tdlist) {
    34. window.localStorage.setItem('todo', JSON.stringify(tdlist))
    35. }
    36. //加载数据
    37. function load() {
    38. var todocount = 0;
    39. var donecount = 0;
    40. /* 删除原来的子节点 */
    41. var olchilds = ol.childNodes;
    42. for (var i = olchilds.length - 1; i >= 0; i--) {
    43. ol.removeChild(olchilds[i]);
    44. }
    45. var ulchilds = ul.childNodes;
    46. for (var i = ulchilds.length - 1; i >= 0; i--) {
    47. ul.removeChild(ulchilds[i]);
    48. }
    49. var data = getData()
    50. data.forEach((item, index) => {
    51. var li = document.createElement('li')
    52. /* li.innerHTML = "

      "+item.title+"

      -"*/
    53. li.innerHTML =
    54. `

      ${index}">${item.title}

      ${index}
      ">-`
    55. if (item.done) {
    56. ul.insertBefore(li, ul.children[0])
    57. li.children[0].checked = 'checked'
    58. donecount++
    59. } else {
    60. ol.insertBefore(li, ol.children[0])
    61. todocount++
    62. }
    63. })
    64. todoCount.innerText = todocount
    65. doneCount.innerText = donecount
    66. }
    67. //编辑数据
    68. function edit() {
    69. ol.addEventListener('click', function(e) {
    70. var p = e.target
    71. if (p.nodeName == 'P') {
    72. p.innerHTML = `${p.innerText}" id="input${p.id}"/>`
    73. p.children[0].select()
    74. p.children[0].addEventListener('blur', function() {
    75. var data = getData()
    76. var i = p.id.substring(1)
    77. data[i].title = this.value
    78. saveData(data)
    79. load()
    80. })
    81. }
    82. })
    83. }
    84. edit()
    85. //删除数据
    86. function remove() {
    87. ol.addEventListener('click', function(e) {
    88. var a = e.target
    89. if (a.nodeName == 'A') {
    90. var i = a.id
    91. var data = getData()
    92. data.splice(i, 1)
    93. saveData(data)
    94. load()
    95. }
    96. })
    97. }
    98. remove()
    99. //切换正在进行和完成
    100. function change() {
    101. ol.addEventListener('click', function(e) {
    102. var input = e.target
    103. if (input.nodeName == 'INPUT') {
    104. var i = input.nextElementSibling.nextElementSibling.id
    105. console.log(i);
    106. var data = getData()
    107. data[i].done = true
    108. saveData(data)
    109. load()
    110. }
    111. })
    112. ul.addEventListener('click', function(e) {
    113. var input = e.target
    114. if (input.nodeName == 'INPUT') {
    115. var i = input.nextElementSibling.nextElementSibling.id
    116. console.log(i);
    117. var data = getData()
    118. data[i].done = false
    119. saveData(data)
    120. load()
    121. }
    122. })
    123. }
    124. change()

     过程:

    enter 按键监听事件存储数据

    给表单文本框绑定一个keydown事件,判断用户是否按下enter键

    确定是按下enter键后,声明一个数组用来获取本地存储中原来的数据

    再把最新的从表单获取的数据追加到数组里面

    最后把数组存储给本地存储并渲染到加载页面

    注意

    在存储事件之前需要进行本地存储以获取并存储数据,保证刷新是数据不会丢失。

    其监听事件的过程是先把数据存储到本地存储中,在从本地存储取出数据加载到页面。

    title.addEventListener('keydown', function(e) {

        /* var e = window.event || e */   //兼容IE浏览器

        var arr = getData() //在获取数据的基础上 拿到数组

        if (e.keyCode == 13) {

            var todo = {

                title: title.value,

                done: false

            }

            arr.push(todo)

            saveData(arr)

            var form = document.querySelector('#form') //让表单返回默认值

            form.reset()

            load()

        }

    })

    存储数据saveDate()

    作用:把数据转化为JSON字符串,再存到本地

    用户按下enter之后,按理来说,应该给本地存储添加数据,但是没有直接的方法,所以,先给本地存储的数组local追加数据,再把这个数组保存到本地;因为本地存储里存储的是字符串,所以要把获取过来的对象数组转换成字符串形式(JSON.stringify)

    function saveData(tdlist) {

        window.localStorage.setItem('todo', JSON.stringify(tdlist))

    }

    获取数据getDate()

    因为本地存储中的数据是字符串型,但是我们希望数组里面存储的是对象数组类型,所以需要用JSON.parse()将字符串转换成数组

    function getData() {

        var data = window.localStorage.getItem('todo')

        if (data != null) {

            return JSON.parse(data)

        } else {

            return []

        }

    }

    加载数据

    数据在页面中的形式是

  • -
    1. 遍历数组,把数据添加到项目里面,用字符串拼接和模板字符串这两种方法
    2. 修改对应数据属性 done 为当前复选框的checked状态
    3. load 加载函数里面,新增一个条件,如果当前数据的done为true 就是已经完成的,就把列表渲染加载到 ul 里面;如果当前数据的done 为false, 则是待办事项,就把列表渲染加载到 ol 里面
    4. 当进行遍历本地存储数据的时候, 如果 数据done为 false, 则 todoCount++, 否则 doneCount++

    function load() {

        var todocount = 0;

        var donecount = 0;

        /* 删除原来的子节点 */

        var olchilds = ol.childNodes;

        for (var i = olchilds.length - 1; i >= 0; i--) {

            ol.removeChild(olchilds[i]);

        }

        var ulchilds = ul.childNodes;

        for (var i = ulchilds.length - 1; i >= 0; i--) {

            ul.removeChild(ulchilds[i]);

        }

        var data = getData()

        data.forEach((item, index) => {

            var li = document.createElement('li')

            /* li.innerHTML = "

    "+item.title+"

    -"*/

            li.innerHTML =

                `

    ${item.title}

    -`

            if (item.done) {

                ul.insertBefore(li, ul.children[0])

                li.children[0].checked = 'checked'

                donecount++

            } else {

                ol.insertBefore(li, ol.children[0])

                todocount++

            }

        })

        todoCount.innerText = todocount

        doneCount.innerText = donecount

    }

    这里要注意删除节点是因为避免增加一个数据到本地存储 ,再添加到项目里渲染函数时保留之前存储的列表数据;即在数组[a, b]里添加一个c 时,理论是[a, b, c],但执行结果是[a, b, a, b, c],保留了之前存储的数据,所以要删除原来的子节点,使结果是[a, b, c].

    编辑数据

    function edit() {

        ol.addEventListener('click', function(e) {

            var p = e.target

            if (p.nodeName == 'P') {

                p.innerHTML = ``

                p.children[0].select()

                p.children[0].addEventListener('blur', function() {

                    var data = getData()

                    var i = p.id.substring(1)

                    data[i].title = this.value

                    saveData(data)

                    load()

                })

            }

        })

    }

    edit()

    删除数据

    点击里面的a链接,不是删除的li,而是删除本地存储对应的数据。

    核心原理:先获取本地存储数据,删除对应的数据,保存给本地存储,重新渲染列表li。

    function remove() {

        ol.addEventListener('click', function(e) {

            var a = e.target

            if (a.nodeName == 'A') {

                var i = a.id

                var data = getData()

                data.splice(i, 1)

                saveData(data)

                load()

            }

        })

    }

    remove()

    切换正在进行和完成

    点击复选框,修改本地存储数据,再重新渲染数据列表。再获取本地存储数据。修改对应数据属性 done 的值添加到正在进行和已完成这两个项目里。保存数据到本地存储,重新渲染加载数据列表。

    function change() {

        ol.addEventListener('click', function(e) {

            var input = e.target

            if (input.nodeName == 'INPUT') {

                var i = input.nextElementSibling.nextElementSibling.id

                console.log(i);

                var data = getData()

                data[i].done = true

                saveData(data)

                load()

            }

        })

        ul.addEventListener('click', function(e) {

            var input = e.target

            if (input.nodeName == 'INPUT') {

                var i = input.nextElementSibling.nextElementSibling.id

                console.log(i);

                var data = getData()

                data[i].done = false

                saveData(data)

                load()

            }

        })

    }

    change()

  • 相关阅读:
    布隆过滤器
    CentOS7.6安装docker
    程序环境和预处理(Program environment and processing)
    MYSQL-JDBC简介
    openEuler 22.03 制作openssh9.5p1rpm包
    js内置对象Date
    安装MinGW win安装gcc
    C语言字符串比较详解:strcmp和strncmp函数的使用方法和规则
    「数据结构详解·六」哈希表
    js生成随机16进制数
  • 原文地址:https://blog.csdn.net/qq_53841687/article/details/126101239