localStorage未加载所有密钥

时间:2017-05-23 09:11:43

标签: javascript

我的简单待办事项有两个问题。我决定添加一个选项,将您的任务保存在本地存储中,并在您下次访问应用程序时加载它们。我已经设法编写了一个函数,通过单击localStorage中的“Zapisz”按钮来保存所有项目,但是当我重新加载页面以加载它们时,它会剪切1或2个项目。

另外,我无法弄清楚如何将相应的类添加到已保存的项目(有两个不同的类,“item”和“itemDone”)。所以这是我的问题,这里是JS代码:

(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));
    };
});
})();

和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>

我知道它并不完美,我很乐意接受对上述代码的批评,但主要是我想解决localStorage问题。

1 个答案:

答案 0 :(得分:1)

问题在于变量i,特别是对于循环:

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

您已经在上面的for循环中声明了i,并且此循环与删除项目的循环重复。我删除了那个循环,我也把你的所有代码都放在了DOMContentLoaded事件中,所以当初始HTML被完全加载和解析时它就可用了。

请注意,在Firefox中,localStorage键的顺序是相反的,因此列表顺序也会反转,在Chrome中它将按预期工作。您应该使用localKey关键字声明var。希望它会有所帮助。

// 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));
        };
    });
});
})();