【问题标题】:To-do app with localStorage带有 localStorage 的待办事项应用程序
【发布时间】:2017-06-07 19:33:12
【问题描述】:

我目前正在编写一个简单的原生 JavaScript 待办事项应用程序。一切看起来都很好,但是在将数据保存到新的 localStorage 时,我做不到,我从未使用过 localStorage,我'阅读了很多文章,当我尝试简单的东西时它可以工作,但我无法让我的应用程序正常工作。我想在 REFRESH 上保存输入的数据,它不会消失,现在的样子……这是应用程序的链接

**** 我想用 VANILLA JAVASCRIPT 来做,而不是 JQUERY ****

My to-do app here!

所以基本上,如果用户做了几个待办事项,并且在刷新时,我希望一切都保持不变,就像在图像中一样。

HTML:

<body>
    <div class="holder">
        <div>
            <input type="text" />
        </div>

        <button id="add">Add</button>

        <div class="results"></div>
    </div>

</body>

JS:

document.addEventListener('DOMContentLoaded',function(){

        let holder = document.querySelector('.holder'),
            addBtn = document.querySelector('#add'),
            removeBtn = document.querySelector('#remove'),
            resultBox = document.querySelector('.results');

        let input = document.getElementsByTagName('input')[0];


        function setAttributes(element,attrs){
            for(let i in attrs){
                element.setAttribute(i,attrs[i]);
            }
        }

        setAttributes(input,{
            'placeholder' : 'Enter To-Do',
            'name' : 'todo'
        });

        function addtoBtn(){

            addBtn.addEventListener('click',function(event){

            if(input.value !== ''){
                let openingDiv = '<div class="todo"><span>';
                let closingDiv = '</span><button class="edit">Edit</button><button class="save">Save</button><button class="removeBtn">Remove</button></div>';

                resultBox.innerHTML += openingDiv + input.value + closingDiv;
                input.value = '';
                event.preventDefault(); 


            } else{
                alert('Enter To-do!');
            }

            let innerBtn = document.querySelectorAll('.removeBtn');
            let editBtn = document.querySelectorAll('.edit');
            let saveBtn = document.querySelectorAll('.save');

            for(let collection = 0 ; collection < saveBtn.length ; collection++){
                saveBtn[collection].style.display = "none";
            }

            function removeToDo(){

                this.parentNode.style.display = 'none';
            }

            for(let k = 0 ; k < innerBtn.length ; k++){
                innerBtn[k].addEventListener('click',removeToDo);
            }

            function startContentEdit(){
                this.previousSibling.contentEditable = true;
                this.previousSibling.style.padding = "10px";
                this.previousSibling.style.boxShadow = "0 0 15px #fff";
                this.previousSibling.style.borderRadius = "10px";
                this.previousSibling.style.transition = "all .4s";

                this.style.display = "none";

                for(let el = 0 ; el < saveBtn.length ; el++){
                    this.nextSibling.style.display = 'inline-block';
                }
            }

            for(let j = 0 ; j < editBtn.length ; j++){
                editBtn[j].addEventListener('click',startContentEdit);
            }

            function saveContentEdit(){
                this.style.display = 'none';

                for(let j = 0 ; j < editBtn.length ; j++){

                    this.previousSibling.style.display = "inline-block";

                    this.parentNode.firstElementChild.style.display = "block";
                    this.parentNode.firstElementChild.contentEditable = false;
                    this.parentNode.firstElementChild.style.padding = "0px";
                    this.parentNode.firstElementChild.style.boxShadow = "0 0 0";
                }
            }

            for(let x = 0 ; x < saveBtn.length ; x++){
                saveBtn[x].addEventListener('click',saveContentEdit);
            }

            }); 
        }

        addtoBtn();
});

正如我所说,我看到了很多文章,但我找不到任何解决方案的答案。 抱歉,这是我的第一个 javascript 应用程序,几乎所有东西都可以在其中运行 :D 我有点兴奋,所以我想让它完全正常运行。

简历:

是否可以使用 localStorage 或 sessionStorage 来保存新生成的

&lt;div class="todo&gt;&lt;/div&gt; 容器?

【问题讨论】:

  • 存储 HTML 元素 而不是其背后的数据听起来是个坏主意。这是很多代码,对于堆栈溢出问题来说可能太多了。您能否更详细地阐明您遇到的问题,并显示与问题相关的代码?

标签: javascript html local-storage


【解决方案1】:

使用本地存储实际上非常简单: 给自己一个参考:

store = window.localStorage;

然后您可以像使用任何其他键值对容器一样在其中存储内容:

store[<key>] = <value>; //or alternatively:
store.setItem(<key>, <value>);

并再次检索值:

val = store[<key>]; //or alternatively:
val = store.getItem(<key>);

要将您的 javascript 对象作为字符串保存在存储中,我建议像这样使用 JSON.stringify() 和 JSON.parse():

store.setItem("todos", JSON.stringify(todos));
todos = JSON.parse(store.getItem("todos"))

这里的“待办事项”几乎可以是任何东西没有循环引用,因为这会混淆 JSON 解析器;>

【讨论】:

    【解决方案2】:

    我正在做一个类似的项目,这里是一个将html保存到本地存储的示例代码

    var myToDos= document.getElementById('myToDos');
    var htmlHolder = { "htmlToDo": myToDos.outerHTML };
    localStorage.setItem('myStorage', JSON.stringify(htmlHolder ));
    

    您可以使用它来检索它

    var myStorage = JSON.parse(localStorage.getItem('myStorage'));
    

    为了加载 html 元素,您需要使用 DOMParser,然后将其附加到您的工作区。

    var parsedHTML = new DOMParser().parseFromString(myStorage.htmlToDo, "text/html");
    

    请注意,“text/html”将返回带有标题和正文的完整 html 源代码,通过检查控制台上的输出并使用 .lastElementChild 等访问相关子项来获取您需要的元素。由于您的容器可能会容纳很多子节点,您所要做的就是遍历 .children 节点列表。

    我告诉你这是完全可能的,因为我自己是在相当绝望的情况下完成的。但请注意,localStorage 非常小,只有 4-10mb 左右,根据浏览器配额不限。

    【讨论】:

      【解决方案3】:

      使用您的原始代码:

      document.addEventListener('DOMContentLoaded',function(){
      
          let history = JSON.parse(localStorage.getItem("todoHistory")) || [];
      
              addBtn = document.querySelector('#add'),
              removeBtn = document.querySelector('#remove'),
          resultBox = document.querySelector('.results');
      
              let input = document.getElementsByTagName('input')[0];
      
      
              function setAttributes(element,attrs){
                  for(let i in attrs){
                      element.setAttribute(i,attrs[i]);
                  }
              }
      
              setAttributes(input,{
                  'placeholder' : 'Enter To-Do',
                  'name' : 'todo'
              });
      
          function applyNewEntry(entry){
              if(input.value !== ''){
                  let openingDiv = '<div class="todo"><span>';
                  let closingDiv = '</span><button class="edit">Edit</button><button class="save">Save</button><button class="removeBtn">Remove</button></div>';
      
                  resultBox.innerHTML += openingDiv + entry + closingDiv;
                  event.preventDefault();
                  return true;
              }
              return false;
          }
      
          function addtoBtn(){
      
              addBtn.addEventListener('click',function(event){
      
              if(applyNewEntry(input.value)){
                  history.push(input.value);
                  input.value = '';
                  localStorage.setItem("todoHistory", history);
              }
              else{
                  alert('Enter To-do!');
              }
      
              let innerBtn = document.querySelectorAll('.removeBtn');
              let editBtn = document.querySelectorAll('.edit');
              let saveBtn = document.querySelectorAll('.save');
      
              for(let collection = 0 ; collection < saveBtn.length ; collection++){
                  saveBtn[collection].style.display = "none";
              }
      
              function removeToDo(){
      
                  this.parentNode.style.display = 'none';
              }
      
              for(let k = 0 ; k < innerBtn.length ; k++){
                  innerBtn[k].addEventListener('click',removeToDo);
              }
      
              function startContentEdit(){
                  this.previousSibling.contentEditable = true;
                  this.previousSibling.style.padding = "10px";
                  this.previousSibling.style.boxShadow = "0 0 15px #fff";
                  this.previousSibling.style.borderRadius = "10px";
                  this.previousSibling.style.transition = "all .4s";
      
                  this.style.display = "none";
      
                  for(let el = 0 ; el < saveBtn.length ; el++){
                      this.nextSibling.style.display = 'inline-block';
                  }
              }
      
              for(let j = 0 ; j < editBtn.length ; j++){
                  editBtn[j].addEventListener('click',startContentEdit);
              }
      
              function saveContentEdit(){
                  this.style.display = 'none';
      
                  for(let j = 0 ; j < editBtn.length ; j++){
      
                      this.previousSibling.style.display = "inline-block";
      
                      this.parentNode.firstElementChild.style.display = "block";
                      this.parentNode.firstElementChild.contentEditable = false;
                      this.parentNode.firstElementChild.style.padding = "0px";
                      this.parentNode.firstElementChild.style.boxShadow = "0 0 0";
                  }
              }
      
              for(let x = 0 ; x < saveBtn.length ; x++){
                  saveBtn[x].addEventListener('click',saveContentEdit);
              }
      
              }); 
          }
      
          addtoBtn();
      });
      

      您需要为您的条目实现某种 UUID 系统,可能通过数据属性将 uuid 保存到 dom 中,这样您就可以相当轻松地编辑/删除它们。

      基本上,我要说明的是没有理由保存 DOM。只是 JSON.stringify 重要的东西(里面的文本)并保存。然后在重新加载时从本地存储中对其进行再水化。

      这是我的codepen

      【讨论】:

        猜你喜欢
        • 2020-09-02
        • 2019-06-02
        • 1970-01-01
        • 1970-01-01
        • 2021-05-03
        • 2015-07-04
        • 1970-01-01
        • 1970-01-01
        • 2020-06-20
        相关资源
        最近更新 更多