2017-05-23 5 views
0

Ich habe zwei Probleme mit meiner einfachen to-do-App. Ich habe beschlossen, eine Option hinzuzufügen, um Ihre Aufgaben im lokalen Speicher zu speichern und sie beim nächsten Besuch der App zu laden. Ich habe es geschafft, eine Funktion zu schreiben, die alle Elemente speichert, indem ich auf "Zapisz" in LocalStorage klicke, aber wenn ich die Seite neu lade, um sie zu laden, schneidet sie 1 oder 2 der Elemente ab.localStorage lädt nicht alle Schlüssel

Auch kann ich nicht herausfinden, wie Sie die passende Klasse zum gespeicherten Element hinzufügen (es gibt zwei verschiedene Klassen, "item" und "itemDone"). Also das ist mein Problem, und hier ist der JS-Code:

(function() { 
/* Load items from localStorage if there are any */ 
window.addEventListener("DOMContentLoaded", function() { 
    var myList = document.getElementById("list"); 
    for (var i = 0; i < localStorage.length; i++) { 
     var item = document.createElement("li"); 
     localKey = localStorage.getItem(localStorage.key(i)); 
     item.innerHTML = JSON.parse(localKey); 
     if (item.innerHTML.indexOf("check") != -1) { 
      item.className = "itemDone"; 
     } else { 
      item.className = "item"; 
     } 
     myList.appendChild(item); 
     var closers = document.getElementsByClassName("closer"); 
     for (var i = 0; i < closers.length; i++) { 
      closers[i].addEventListener("click", deleteItem); 
     } 
    }; 
}); 

/* This function deletes parent element of clicked element - in this case a clicked element will be a "span" element with "closer" class, and it's parent is "li" element */ 
function deleteItem() { 
    this.parentNode.parentNode.removeChild(this.parentNode); 
}; 

/* this function allows to delete item from the loist */ 
var x = document.getElementsByClassName("closer"); // get all elements with "closer" class 
for (var i = 0; i < x.length; i++) { // simple loop that adds eventListener to all elements with "closer" class 
    x[i].addEventListener("click", deleteItem); // on click function "deleteItem" is invoked 
}; 

/* This function adds "li" element to the list with text value from input #newInput, and then adds a span with innertext "X" and class .closer */ 
function addItem() { 
    var myList = document.getElementById("list"); // get the main list ("ul") 
    var newListItem = document.createElement("li"); //create a new "li" element 
    var itemText = document.getElementById("newInput").value; // read the input value from #newInput 
    var listText = document.createTextNode(itemText); // create text node with calue from input 
    newListItem.appendChild(listText); // add text node to new "li" element 
    newListItem.className = "" 
    if (itemText === "") { // if input value is empty 
     alert("Pole nie może być puste"); // show this alert 
    } else { // if it's not empty 
     var x = document.createElement("span"); // create a new "span" element 
     x.innerText = "X"; // add inner text to "span" element 
     x.className = "closer"; // add class to "span" element 
     x.addEventListener("click", deleteItem, false); 
     myList.appendChild(newListItem); // add created "li" element to "ul" 
     newListItem.className = "item"; // add class to new "li" element 
     newListItem.appendChild(x); // add a "span" to new "li" element 
     var itemText = document.getElementById("newInput"); // read current input value 
     itemText.value = ""; // set current input value to null 
    } 
}; 
/* addButton reffers to the button used to add new elements to the list. After clicking it, function "addItem" is called */ 
var addButton = document.getElementById("createNew"); // fetch the "createNew" button 
addButton.addEventListener("click", addItem); // add click event to "createNew" button and run function 
/* This function clears all added elements from the list */ 

/* This script adds a method in which you can also add a new "li" item with "enter" keydown */ 
var textAdd = document.getElementById("newInput"); // target input 
textAdd.addEventListener ("keypress", function (e) { // add event listener on "keypress" 
    var key = e.which || e.keyCode; // which key is being used 
    if (key === 13){ // if pressed key is "enter" (13) 
    e.preventDefault(); // prevent default "enter" action 
    addItem(); // addItem function is invoked 
    }; 
}); 

function clearList(){ 
    var myList = document.getElementById("list"); // get the "ul" element 
    myList.innerHTML = ""; // clear all it's children 
    window.localStorage.clear(); 
}; 
/* deleteAll variable reffers the button used to clear all items. After clicking it, function "deleteAll" is called */ 
var deleteAll = document.getElementById("deleteAll"); // fetch the "deleteAll" button 
deleteAll.addEventListener("click", clearList); // add click event to "deleteAll" button and run finction 

/* This code changes the class of clicked "li" element from "item" to "itemDone" using event delegation method */ 
document.getElementById("list").addEventListener("click", function(e) { 
    if (e.target && e.target.matches("li.item")) { // if event target matches an "li" item with "item" class 
     e.target.className = "itemDone"; // change class to "itemDone" 
     var check = document.createElement("i"); // create new "i" element 
     check.className = "fa fa-check done"; // add class to "i" element 
     e.target.appendChild(check); // add new "i" element to event target ("li") 
    } else if (e.target && e.target.matches("li.itemDone")) {// if event target matches an "li" item with "itemDone" class 
    e.target.className = "item"; // change class to "item" 
     var done = e.target.getElementsByClassName("done"); // choose target with "done" class 
     for (var i = 0; i < done.length; i++) { 
     e.target.removeChild(done[i]); // remove "i" element with "done" class from target 
     }; 
    }; 
}); 

/* Save all "li" items form the list to localStorage */ 
var saveAll = document.getElementById("saveAll"); 
saveAll.addEventListener("click", function() { 
    var item = document.getElementsByTagName("li"); 
    for (var i = 0; i < item.length; i++) { 
     localStorage.setItem([i], JSON.stringify(item[i].innerHTML)); 
    }; 
}); 
})(); 

Und HTML:

<!DOCTYPE html> 
<html lang="pl"> 
<head> 
<meta charset="UTF-8"> 
    <meta http-equiv="X-UA-Compatible" content="IE=edge"> 
    <meta name="viewport" content="width=device-width, initial-scale=1"> 
    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Sansita&amp;subset=latin-ext"> 
    <link rel="stylesheet" href="css/font-awesome.min.css"> 
    <link rel="stylesheet" href="css/main.css"> 
    <title>Prosta aplikacja To-Do list</title> 
    <meta name="description" content="Prosta aplikacja zadań To-Do"> 
    <meta name="keywords" content="aplikacja, to-do, lista, zadań, javascript"> 
    <meta name="author" content="Michał Grochowski"> 
</head> 
<body> 
<header id="header"> 
    <div class="description"> 
    <h1>Prosta aplikacja To-Do</h1> 
    </div> 
</header> 
<section> 
    <div class="mainlist"> 
     <form class="form"> 
      <input id="newInput" type="text" placeholder="Dodaj pozycję"> 
      <button id="createNew" type="button">Dodaj</button> 
     </form> 
     <h2>Moja lista:</h2> 
     <div class="listBg"> 
      <ul id="list"> 
      </ul> 
     </div> 
     <div class="flex-row"> 
      <button id="deleteAll" type="button">Wyczyść</button> 
      <button id="saveAll" type="button">Zapisz</button> 
     </div> 
     <p class="helpText">Żeby dodać pozycję do listy wpisz tekst w polu "Dodaj pozycję", a następnie kliknij przycisk "Dodaj" lub wciśnij enter.</p> 
     <p class="helpText">Kliknij wybrane zadanie, żeby oznaczyć je jako wykonane. W ten sam sposób możesz je odznaczyć.</p> 
     <p class="helpText">Usuń wybraną pozycję z listy kilkając "X" w prawym rogu.</p> 
     <p class="helpText">Żeby zapisac listę w pamięci przeglądarki, kliknij przycisk "Zapisz".</p> 
     <p class="helpText">Żeby wyczyścić całą listę, kliknij przycisk "Wyczyść".</p> 
    </div> 
</section> 
<footer> 
    <div class="footer"> 
    <p>&copy 2017 <a href="http://dobrywebdev.pl" target="_blank">Michał Grochowski - Dobrywebdev.pl</a></p> 
    </div> 
</footer> 
<script src="js/script.js"></script> 
</body> 
</html> 

Ich weiß, dass es nicht perfekt ist und ich werde gerne jede Kritik an obigem Code akzeptieren, vor allem aber ich möchte dieses localStorage-Problem lösen.

+0

Vielleicht sind Sie das Erreichen der [max Begrenzung local] (https://stackoverflow.com/questions/2989284/what-is-the-max-size-of-localstorage-values)? – George

+0

Wahrscheinlich nicht, auch nach dem Hinzufügen von 2 Elementen, wenn ich die Seite aktualisieren lädt es nur 1. – grhu

Antwort

1

Problem ist mit variabler i, speziell diese for-Schleife:

var closers = document.getElementsByClassName("closer"); 
    for (var i = 0; i < closers.length; i++) { 
     closers[i].addEventListener("click", deleteItem); 
    } 

Du hast bereits i in der for-Schleife oben erklärt, und diese Schleife ist ein Duplikat der Schleife unter dem ein Element löscht. Ich habe diese Schleife gelöscht, auch habe ich Ihren gesamten Code in DOMContentLoaded Ereignis, so dass es verfügbar sein wird, wenn das ursprüngliche HTML vollständig geladen und geparst wurde.

Beachten Sie, dass in Firefox die Reihenfolge der localStorage-Tasten umgekehrt ist, so Liste Reihenfolge wird ebenfalls umgekehrt werden, in Chrome wird es wie vorgesehen funktionieren. Und Sie sollten localKey mit var Schlüsselwort erklären. Hoffe es wird helfen.

// Not needed, but it helps, like with localKey declaration. 
"use strict"; 

(function() { 
/* Load items from localStorage if there are any */ 
window.addEventListener("DOMContentLoaded", function() { 
    var myList = document.getElementById("list"); 

    for (var i = 0; i < localStorage.length; i++) { 
     var item = document.createElement("li"); 
     var localKey = localStorage.getItem(localStorage.key(i)); 
     item.innerHTML = JSON.parse(localKey); 
     if (item.innerHTML.indexOf("check") != -1) { 
      item.className = "itemDone"; 
     } else { 
      item.className = "item"; 
     } 
     myList.appendChild(item); 
    }; 

    /* This function deletes parent element of clicked element - in this case a clicked element will be a "span" element with "closer" class, and it's parent is "li" element */ 
    function deleteItem() { 
     this.parentNode.parentNode.removeChild(this.parentNode); 
    }; 

    // TODO: Not a function, wasn't working because all code needed to be inside addEventListener("DOMContentLoaded", like now. 
    /* this function allows to delete item from the loist */ 
    var x = document.getElementsByClassName("closer"); // get all elements with "closer" class 

    for (var i = 0; i < x.length; i++) { // simple loop that adds eventListener to all elements with "closer" class 
     x[i].addEventListener("click", deleteItem); // on click function "deleteItem" is invoked 
    }; 

    /* This function adds "li" element to the list with text value from input #newInput, and then adds a span with innertext "X" and class .closer */ 
    function addItem() { 
     var myList = document.getElementById("list"); // get the main list ("ul") 
     var newListItem = document.createElement("li"); //create a new "li" element 
     var itemText = document.getElementById("newInput").value; // read the input value from #newInput 
     var listText = document.createTextNode(itemText); // create text node with calue from input 
     newListItem.appendChild(listText); // add text node to new "li" element 
     newListItem.className = "" 
     if (itemText === "") { // if input value is empty 
      alert("Pole nie może być puste"); // show this alert 
     } else { // if it's not empty 
      var x = document.createElement("span"); // create a new "span" element 
      x.innerText = "X"; // add inner text to "span" element 
      x.className = "closer"; // add class to "span" element 
      x.addEventListener("click", deleteItem, false); 
      myList.appendChild(newListItem); // add created "li" element to "ul" 
      newListItem.className = "item"; // add class to new "li" element 
      newListItem.appendChild(x); // add a "span" to new "li" element 
      var itemText = document.getElementById("newInput"); // read current input value 
      itemText.value = ""; // set current input value to null 
     } 
    }; 
    /* addButton reffers to the button used to add new elements to the list. After clicking it, function "addItem" is called */ 
    var addButton = document.getElementById("createNew"); // fetch the "createNew" button 
    addButton.addEventListener("click", addItem); // add click event to "createNew" button and run function 
    /* This function clears all added elements from the list */ 

    /* This script adds a method in which you can also add a new "li" item with "enter" keydown */ 
    var textAdd = document.getElementById("newInput"); // target input 
    textAdd.addEventListener ("keypress", function (e) { // add event listener on "keypress" 
     var key = e.which || e.keyCode; // which key is being used 
     if (key === 13){ // if pressed key is "enter" (13) 
     e.preventDefault(); // prevent default "enter" action 
     addItem(); // addItem function is invoked 
     }; 
    }); 

    function clearList(){ 
     var myList = document.getElementById("list"); // get the "ul" element 
     myList.innerHTML = ""; // clear all it's children 
     window.localStorage.clear(); 
    }; 
    /* deleteAll variable reffers the button used to clear all items. After clicking it, function "deleteAll" is called */ 
    var deleteAll = document.getElementById("deleteAll"); // fetch the "deleteAll" button 
    deleteAll.addEventListener("click", clearList); // add click event to "deleteAll" button and run finction 

    /* This code changes the class of clicked "li" element from "item" to "itemDone" using event delegation method */ 
    document.getElementById("list").addEventListener("click", function(e) { 
     if (e.target && e.target.matches("li.item")) { // if event target matches an "li" item with "item" class 
      e.target.className = "itemDone"; // change class to "itemDone" 
      var check = document.createElement("i"); // create new "i" element 
      check.className = "fa fa-check done"; // add class to "i" element 
      e.target.appendChild(check); // add new "i" element to event target ("li") 
     } else if (e.target && e.target.matches("li.itemDone")) {// if event target matches an "li" item with "itemDone" class 
     e.target.className = "item"; // change class to "item" 
      var done = e.target.getElementsByClassName("done"); // choose target with "done" class 
      for (var i = 0; i < done.length; i++) { 
      e.target.removeChild(done[i]); // remove "i" element with "done" class from target 
      }; 
     }; 
    }); 

    /* Save all "li" items form the list to localStorage */ 
    var saveAll = document.getElementById("saveAll"); 
    saveAll.addEventListener("click", function() { 
     var item = document.getElementsByTagName("li"); 
     for (var i = 0; i < item.length; i++) { 
      localStorage.setItem([i], JSON.stringify(item[i].innerHTML)); 
     }; 
    }); 
}); 
})(); 
+0

Wow, danke für Ihre Hilfe :) Wie immer, ein oder zwei dumme Fehler können unbemerkt bleiben und ganze Skripte verhält sich nicht wie du will es. Aber ich bin neugierig, warum lädt Firefox User-Agent localStorage-Schlüssel in anderer Reihenfolge als Chrome oder Edge? Ich konnte neben einem kleinen Eintrag in MDN keine Informationen darüber finden, dass Sie dieser Bestellung nicht vertrauen sollten. – grhu

+0

Gerne helfen! Es ist für mich auch interessant, leider konnte ich die Antwort nicht finden. Manchmal implementieren Browser Dinge anders. – Zero

+0

Nun, vielleicht werde ich versuchen, mehr darüber zu erfahren. :) Wie auch immer, danke nochmal für deine Hilfe. – grhu

Verwandte Themen