简体   繁体   中英

Changes to localstorage not going right

I have something like the Todo app with the ability to delete, edit and save to localstorage. There is a problem with editing. When I created 1 task and tried to edit it, everything went well and the changes were saved. But when I created 2 tasks on the page and tried to edit the last (lower) one, nothing happened, more precisely, this task (which I edited) disappeared. Simply put, no matter how many tasks there are on the page, I can only edit the top one (on the page) How to make it so that you can edit any task?

HTML

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" href="assets/css/style.css" />
    <title>Document</title>
  </head>
  <body>
    <div class="container">
      <div class="sett">
        <input type="text" name="" class="input" placeholder="Введите задачу" />
        <button class="button">Добавить</button>
      </div>
      <div class="list">
        <ul class="ul"></ul>
      </div>
    </div>
    <button class="delete_sto">Удалит local</button>
    <!-- <button class="button_delete">Удалить все</button> -->
    <!-- <button class="red">Речить все</button> -->
    <script src="assets/js/main.js"></script>
  </body>
</html>

CSS

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
body {
  background-color: gray;
}
.container {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background-color: chocolate;
  width: 900px;
  min-height: 500px;
}
.sett {
  text-align: center;
  margin-top: 15px;
}
.sett input {
  width: 200px;
  height: 40px;
  border: none;
  border-radius: 25px;
  outline: none;
  padding-left: 5px;
}
.sett button {
  width: 200px;
  height: 40px;
  border: none;
  border-radius: 25px;
}
.list {
  margin-top: 10px;
  margin-left: 10px;
}
.task {
  margin-top: 15px;
  background-color: blueviolet;
  min-width: 300px;
  min-height: 50px;
}
.buttons {
  display: flex;
}
.button_delete {
  width: 200px;
  height: 40px;
  border: none;
  border-radius: 25px;
  background-color: rgb(135, 29, 29);
}
.red {
  width: 200px;
  height: 40px;
  border: none;
  border-radius: 25px;
  background-color: rgb(16, 118, 219);
}
.text {
  border: 1px solid black;
  width: auto;
  height: 200px;
}

JS

//ИНИЦИЛИЗАЦИЯ

let input = document.querySelector(".input"); //Текст таска
let create_task = document.querySelector(".button"); //Создать
let ul = document.querySelector(".ul");
let delete_sto = document.querySelector(".delete_sto");

create_task.addEventListener("click", newtask);

let task = document.querySelector(".task");

delete_sto.addEventListener("click", function () {
  localStorage.clear();
});

let obj = {};

for (let i = 0; i < localStorage.length; i++) {
  let key = localStorage.key(i);
  ul.innerHTML += `<div class="task">
                ${localStorage.getItem(key)}
                </div>`;
}

function newtask() {
  let date = new Date();
  //Добавление таска на страницу
  ul.insertAdjacentHTML(
    "afterbegin",
    `
      <div class="task">
          <div class="text" contenteditable="true">
            ${input.value}
          </div>

          <button class="button_delete">Удалить</button>
          <button class="check">Добавить checkbox</button>
          <button class="red">Редактировать</button>
          <p class="data">${
            date.getHours() + ":" + date.getMinutes() + ":" + date.getSeconds()
          }</p>
      </div>
    `
  );
  //Сохранение таска в localstorage
  let HTMLtask = document.querySelector(".task");
  let HTMLparse = HTMLtask.innerHTML;
  localStorage.setItem(input.value, HTMLparse);

  //УДАЛИТЬ
  let button_del = document.querySelector(".button_delete");
  button_del.addEventListener("click", del);

  //РЕДАКТИРОВАТЬ
  let red = document.querySelector(".red");
  red.addEventListener("click", redd);

  //Добавить чекбокс
  let newcheck = document.querySelector(".check");
  newcheck.addEventListener("click", function () {
    let oldkey = localStorage.key(this.parentNode.children[0].innerText);
    localStorage.removeItem(oldkey);

    let tasktext = document.querySelector(".text");

    let ch = document.createElement("input");
    ch.type = "checkbox";
    tasktext.append(ch);

    let HTMLtask = document.querySelector(".task");
    let HTMLparse = HTMLtask.innerHTML;
    let newkey = red.parentNode.children[0].innerText;

    localStorage.setItem(newkey, HTMLparse);
  });
}

let button_del = document.querySelector(".button_delete");
button_del.addEventListener("click", del);

let red = document.querySelectorAll(".red");
red.addEventListener("click", redd);

function redd() {
  let red = document.querySelector(".red");
  let oldkey = localStorage.key(red.parentNode);
  console.log(oldkey);
  localStorage.removeItem(oldkey);
  let newkey = red.parentNode.children[0].innerText;
  console.log(newkey);
  let parse = this.parentNode.innerHTML;
  console.log(parse);
  localStorage.setItem(newkey, parse);
}

function del() {
  let button_del = document.querySelector(".button_delete");
  button_del.parentNode.remove();
  let key = localStorage.key(this);
  localStorage.removeItem(key);
}

look, the problem is that you bind a function to all tasks that will always refer only to the first element

function redd() {
  let red = document.querySelector(".red");
  let oldkey = localStorage.key(red.parentNode);
  console.log(oldkey);
  localStorage.removeItem(oldkey);
  let newkey = red.parentNode.children[0].innerText;
  console.log(newkey);
  let parse = this.parentNode.innerHTML;
  console.log(parse);
  localStorage.setItem(newkey, parse);
}

let red = document.querySelector(".red"); because all of your tasks has that .red class, this selector will always work with the first one

try to use context this for example

function redd() {
  console.log(this.parentNode.children[0].innerText)
...

the second problem is that you use the key in localstorage as input field.
and when you start editing the task, you can't get the oldkey right anymore.

i would use something like that

let date = new Date
let uniqueID = date.getUTCMilliseconds()
ul.insertAdjacentHTML('afterbegin',
    `
        <div class="task" id="${uniqueID}">

            <div class="text" contenteditable="true">
            ${input.value}

            </div>

            <button class="button_delete">Удалить</button>
            <button class="check">Добавить checkbox</button>
            <button class="red">Редактировать</button>
            <p class="data">${date.getHours() + ':' + date.getMinutes() + ':' + date.getSeconds()}</p>
        </div>
        `
  )
let HTMLtask = document.querySelector('.task')
let HTMLparse = HTMLtask.innerHTML
localStorage.setItem(uniqueID, HTMLparse)

As you see, I created uniqueID
and added it to task div as id
and used it for localstorage key
it will be helpful for editing task
in that way it would be easy to get id task (localstorage key) that I described higher


the third problem

let red = document.querySelectorAll(".red");
red.addEventListener("click", redd);

after .querySelectorAll you get node list array, not a function
and you can't use function method for that
should be something like that

let red = document.querySelectorAll('.red')
for (let i = 0; i < red.length; i++) {
  red[i].addEventListener('click', redd)
}

suggestion
save to localstorage only data of task (date, text, status),
not entire html
In the future, if you will want to change the design of project,
How you will change the html in all your localstorage???

Many problems with your code:

  1. "querySelector" always gets first element. You added event to only first element ===> Only the first task can be edited or deleted.
  2. "querySelectorAll: return an array called node list. You cann't add event to a node list, you just can add event to special node.
  3. Don't use content of task for a key. If two tasks have same content that cause an error. let's create a unique key.Because it's just an example, you can use timestamp for key, that's fast and easy way..
    I fixed "del" and "red" in your code, see below. Just copy and replace all your javascript code. You can fix "check" by yourself.
let input = document.querySelector('.input') //Текст таска
let create_task = document.querySelector('.button') //Создать
let ul = document.querySelector('.ul')
let delete_sto = document.querySelector('.delete_sto')

create_task.addEventListener('click', newtask)

let task = document.querySelector('.task')

delete_sto.addEventListener('click', function () {
    localStorage.clear()
})

let obj = {}

for (let i = 0; i < localStorage.length; i++) {
    let key = localStorage.key(i)
    ul.innerHTML += `<div class="task">
    ${localStorage.getItem(key)}
    </div>`
}

function newtask() {
    let date = new Date();
    let id = date.valueOf();
    //Добавление таска на страницу
    ul.insertAdjacentHTML('afterbegin',
        `
    <div class="task">

        <div class="text" contenteditable="true">
        ${input.value}

        </div>

        <button class="button_delete" onclick="del(this,${id});">Удалить</button>
        <button class="check" ">Добавить checkbox</button>
        <button class="red" onclick="redd(this,${id});">Редактировать</button>
        <p class="data">${date.getHours() + ':' + date.getMinutes() + ':' + date.getSeconds()}</p>
    </div>
    `
    )
    //Сохранение таска в localstorage
    let HTMLtask = document.querySelector('.task')
    let HTMLparse = HTMLtask.innerHTML
    localStorage.setItem(id, HTMLparse)

    //УДАЛИТЬ
    // let button_del = document.querySelector('.button_delete')
    // button_del.addEventListener('click', del)

    //РЕДАКТИРОВАТЬ
    // let red = document.querySelector('.red')
    // red.addEventListener('click', redd)

    //Добавить чекбокс
    // let newcheck = document.querySelector('.check')
    // newcheck.addEventListener('click', function () {
    //     let oldkey = localStorage.key(this.parentNode.children[0].innerText)
    //     localStorage.removeItem(oldkey)

    //     let tasktext = document.querySelector('.text')

    //     let ch = document.createElement('input')
    //     ch.type = 'checkbox'
    //     tasktext.append(ch)

    //     let HTMLtask = document.querySelector('.task')
    //     let HTMLparse = HTMLtask.innerHTML
    //     let newkey = red.parentNode.children[0].innerText
    //     localStorage.setItem(newkey, HTMLparse)
    // })
}


// let button_del = document.querySelector('.button_delete')
// button_del.addEventListener('click', del)

// let red = document.querySelectorAll('.red')
// red.addEventListener('click', redd)


function redd(e, id) {
    console.log(id);
    localStorage.removeItem(id)
    let parse = e.parentNode.outerHTML
    localStorage.setItem(id, parse)
}

function del(e, id) {
    e.parentNode.remove()
    localStorage.removeItem(id)
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM