【问题标题】:Clearing local storage in JavaScript在 JavaScript 中清除本地存储
【发布时间】:2020-11-19 14:25:12
【问题描述】:

我正在使用 vanilla JavaScript 制作一个简单的待办事项列表。

我已成功将用户的任务存储在本地存储中,并在前端显示该任务。

有一个清除任务按钮可以从本地存储和前端删除这两个任务。

它有效,但并不完美。

当我执行以下操作时失败:

  1. 添加任务
  2. 清除任务
  3. 添加一个新任务,该特定任务仅出现在前端,但在本地存储上之前清除的任务和新任务出现。

如果我随后重新加载浏览器,则在前端和本地存储中清除的上一个任务会同时出现在前端和本地存储中。

请问如何让它完美运行?

即一旦我清除本地存储中的任务,该任务就不会再次出现。

下面是我的代码

JavaScript 代码 sn-p

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

const form = document.querySelector('form');

const ul = document.querySelector('ul');

const clearTask = document.querySelector('#clear');

// A list for task in local storage
const itemsLocal = localStorage.getItem("items") ? JSON.parse(localStorage.getItem("items")) : [];

localStorage.setItem("items", JSON.stringify(itemsLocal))

// convert local storage data to something I can work with in userData variable
const userData = JSON.parse(localStorage.getItem("items"));


// Function to add task
const addTask = (text) => {
// Create li element
const li = document.createElement('li');

// Create text node
li.appendChild(document.createTextNode(text));

ul.appendChild(li);
}

form.addEventListener('submit',(e) => {
    e.preventDefault();

    //  Add user task to local storage
    itemsLocal.push(task.value);  
    localStorage.setItem("items", JSON.stringify(itemsLocal))

    addTask(task.value);   
    
    // Clear input field
    task.value = '';
})


userData.forEach((data)=> {
    addTask(data);
});

clearTask.addEventListener('click', () =>{
    localStorage.removeItem("items");
    userData.length = 0;
    while (ul.firstChild) {
        ul.removeChild(ul.firstChild);
    }
    
})

HTML

<body>
    <form action="">
        <input type="text">
        <button type="submit">Add  Task</button>
    </form>
    <div>
        <ul>
            
        </ul>
    </div>
    <button id="clear">Clear Task</button>
    <script src="main.js"></script>
</body>

P.s 我对 JavaScript 有点陌生。

【问题讨论】:

标签: javascript local-storage


【解决方案1】:

在您的 clearTask 事件侦听器中,您还必须清除您的 itemsLocal 数组。

clearTask.addEventListener('click', () =>{
    localStorage.removeItem("items");
    itemsLocal.length = 0; // clear it here... (you got to add this line)
    userData.length = 0;
    while (ul.firstChild) {
        ul.removeChild(ul.firstChild);
    }
});

目前,由于您没有清除它,因此您正在将新值添加到仍然包含旧值的数组中,并将其存储到本地存储中。

form.addEventListener('submit',(e) => {
    e.preventDefault();

    // 'itemsLocal' still has your old values here and you're just appending to it
    itemsLocal.push(task.value);

    // storing old items and the new one in the local storage here
    localStorage.setItem("items", JSON.stringify(itemsLocal));

    // you're rendering only the currently added item so you get the
    // fake feeling that your list is fine and that local storage has issues
    addTask(task.value);  
    
    // Clear input field
    task.value = '';
});

【讨论】:

    【解决方案2】:
    • 只需将clearTask 中的用户数据数组设为空,如下所示:
    clearTask.addEventListener('click', () =>{
        localStorage.removeItem("items");
        itemsLocal = [];
        userData = [];
    
    })
    

    【讨论】:

      【解决方案3】:

      elementsList.innerHTML = '' 将清除列表中的所有项目。

      以下代码与 localStorage 完美配合,它还有一个额外的功能可以删除单个项目。

      HTML:

      <section class="container">
          <h1>TO DO LIST</h1>
          <ul></ul>
          <div class="footer">
              <input type="text" placeholder="Title..." />
              <button class="enter">Enter</button>
          </div>
          <div>
              <button class="clear">
                  Clear
              </button>
          </div>
      </section>
      

      脚本:

      const ul = document.querySelector("ul");
      const input = document.querySelector("input");
      const enterBtn = document.querySelector(".enter");
      const clearBtn = document.querySelector(".clear");
      
      const LIST_LS = "lists";
      let lists = [];
      
      function saveStorage() {
        localStorage.setItem(LIST_LS, JSON.stringify(lists));
      }
      
      function clearStorage() {
        lists = [];
        ul.innerHTML = "";
        saveStorage();
      }
      
      function loadStorage() {
        const loadStorage = localStorage.getItem(LIST_LS);
      
        if (!loadStorage) {
          return;
        }
        const parsedList = JSON.parse(loadStorage);
        parsedList.forEach(list => createItem(list.text));
      }
      
      function onAdd() {
        const text = input.value;
      
        if (!text) {
          return input.focus();
        }
        createItem(text);
        input.value = "";
        input.focus();
      }
      
      function createItem(text) {
        const id = lists.length + 1;
        const itemRow = document.createElement("li");
        itemRow.setAttribute("class", "item__row");
        itemRow.innerHTML = `${text} <i class="fas fa-trash-alt" data-id=${
          itemRow.id
        }></i>`;
        itemRow.id = id;
      
        const delBtn = itemRow.querySelector(".fa-trash-alt");
        delBtn.addEventListener("click", deleteItem);
      
        ul.appendChild(itemRow);
        lists.push({ text, id });
        saveStorage();
        return itemRow;
      }
      
      function deleteItem(event) {
        const trashBtn = event.target;
        const li = trashBtn.parentNode;
        ul.removeChild(li);
        const cleanStorage = lists.filter(toDo => toDo.id !== +li.id);
        lists = cleanStorage;
        saveStorage();
      }
      
      function init() {
        loadStorage();
      
        enterBtn.addEventListener("click", () => onAdd());
      
        input.addEventListener("keypress", event => {
          if (event.key === "Enter") {
            onAdd();
          }
        });
      
        clearBtn.addEventListener("click", () => clearStorage());
      }
      
      init();
      

      https://codesandbox.io/s/damp-morning-csiny

      【讨论】:

        【解决方案4】:

        看看这个,我想你可以从代码中学习:

        //<![CDATA[
        /* js/external.js */
        let get, post, doc, htm, bod, nav, M, I, mobile, S, Q, hC, aC, rC, tC, shuffle, rand, Lister; // for use on other loads
        addEventListener('load', ()=>{
        get = (url, success, context)=>{
          const x = new XMLHttpRequest;
          const c = context || x;
          x.open('GET', url);
          x.onload = ()=>{
            if(success)success.call(c, JSON.parse(x.responseText));
          }
          x.send();
        }
        post = function(url, send, success, context){
          const x = new XMLHttpRequest;
          const c = context || x;
          x.open('POST', url);
          x.onload = ()=>{
            if(success)success.call(c, JSON.parse(x.responseText));
          }
          if(typeof send === 'object' && send && !(send instanceof Array)){
            if(send instanceof FormData){
              x.send(send);
            }
            else{
              const fd = new FormData;
              for(let k in send){
                fd.append(k, JSON.stringify(send[k]));
              }
              x.send(fd);
            }
          }
          else{
            throw new Error('send argument must be an Object');
          }
          return x;
        }
        doc = document; htm = doc.documentElement; bod = doc.body; nav = navigator; M = tag=>doc.createElement(tag); I = id=>doc.getElementById(id);
        mobile = nav.userAgent.match(/Mobi/i) ? true : false;
        S = (selector, within)=>{
          var w = within || doc;
          return w.querySelector(selector);
        }
        Q = (selector, within)=>{
          var w = within || doc;
          return w.querySelectorAll(selector);
        }
        hC = function(node, className){
          return node.classList.contains(className);
        }
        aC = function(){
          const a = [].slice.call(arguments), n = a.shift();
          n.classList.add(...a);
          return aC;
        }
        rC = function(){
          const a = [].slice.call(arguments), n = a.shift();
          n.classList.remove(...a);
          return rC;
        }
        tC = function(){
          const a = [].slice.call(arguments), n = a.shift();
          n.classList.toggle(...a);
          return tC;
        }
        shuffle = array=>{
          let a = array.slice(), i = a.length, n, h;
          while(i){
            n = Math.floor(Math.random()*i--); h = a[i]; a[i] = a[n]; a[n] = h;
          }
          return a;
        }
        rand = (min, max)=>{
          let mn = min, mx = max;
          if(mx === undefined){
            mx = mn; mn = 0;
          }
          return mn+Math.floor(Math.random()*(mx-mn+1));
        }
        Lister = function(inInput, addButton, outList, clearButton, reverseButton, controlDiv = null){
          const o = localStorage.listObj ? JSON.parse(localStorage.listObj) : {lastFirst:true, list:[]}, la = o.list;
          outList.innerHTML = '';
          this.lastFirst = o.lastFirst;
          this.save = ()=>{
            localStorage.listObj = JSON.stringify(o);
            return this;
          }
          this.createItem = value=>{
            let li = M('li'), x = M('input');
            x.className = 'warn'; x.type = 'button'; x.value = 'REMOVE'; li.textContent = value; li.appendChild(x);
            x.onclick = ()=>{
              for(let i=0,c=outList.children,l=c.length; i<l; i++){
                if(c[i] === li){
                  la.splice(i, 1); break;
                }
              }
              outList.removeChild(li);
              if(controlDiv && !outList.hasChildNodes())aC(controlDiv, 'hid');
              this.save();
            }
            return li;
          }
          this.addItem = value=>{
            let v = value.trim();
            if(v !== ''){
              let li = this.createItem(v), fc = outList.firstChild;
              if(this.lastFirst && fc){
                outList.insertBefore(li, fc); la.unshift(v);
              }
              else{
                outList.appendChild(li); la.push(v);
              }
              this.save();
              if(controlDiv)rC(controlDiv, 'hid');
            }
          }
          const addIt = ()=>{
            this.addItem(inInput.value); inInput.value = ''; rC(inInput, 'good');
          }
          addButton.onclick = ()=>{
            addIt();
          }
          inInput.onkeydown = e=>{
            if(e.key === 'Enter')addIt();
          }
          inInput.oninput = function(){
            const f = this.value.trim() === '' ? rC : aC;
            f(this, 'good');
          }
          clearButton.onclick = function(){
            localStorage.removeItem('listObj'); la.splice(0); outList.innerHTML = '';
            if(controlDiv)aC(controlDiv, 'hid');
          }
          this.reverse = ()=>{
            la.reverse(); outList.innerHTML = '';
            la.forEach(v=>{
              outList.appendChild(this.createItem(v));
            });
            o.lastFirst = this.lastFirst = !this.lastFirst; localStorage.listObj = JSON.stringify(o);
          }
          reverseButton.onclick = ()=>{
            this.reverse();
          }
          if(la.length){
            la.forEach(v=>{
              outList.appendChild(this.createItem(v));
            });
          }
          if(controlDiv && outList.hasChildNodes())rC(controlDiv, 'hid');
        }
        // magic under here
        const lister = new Lister(I('input_item'), I('add_item'), I('items'), I('clear'), I('reverse'), I('control'));
        }); // end load
        //]]>
        /* css/external.css */
        *{
          box-sizing:border-box; font:22px Tahoma, Geneva, sans-serif; color:#000; padding:0; margin:0; overflow:hidden;
        }
        html,body,.main{
          width:100%; height:100%;
        }
        .main{
          background:#333; overflow-y:auto;
        }
        input[type=text].good{
          border:1px solid #0c0;
        }
        .hid{
          display:none;
        }
        #lister{
          padding:10px; background:#aaa;
        }
        input{
          height:38px; padding:3px 5px;
        }
        input[type=text]{
          width:calc(100% - 70px); background:#fff; border:1px solid #c00; border-radius:3px;
        }
        input[type=button]{
          color:#fff; font-weight:bold; border:0; border-radius:5px; cursor:pointer;
        }
        #add_item{
          width:70px; background:linear-gradient(#679467,#235023);
        }
        li{
          position:relative; height:32px; background:#ccc; padding:3px 10px; margin:5px;
        }
        .warn{
          background:linear-gradient(#b75757,#502323); padding:3px 15px;
        }
        li>.warn{
          position:absolute; right:5px; height:26px; font-size:14px;
        }
        #control{
          background:#bbb; text-align:center; padding:5px; border:5px solid #ccc;
        }
        #reverse.warn{
          background:linear-gradient(#1b7bbb,#147);
        }
        .warn+.warn{
          margin-left:20px;
        }
        <!DOCTYPE html>
        <html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'>
          <head>
            <meta charset='UTF-8' /><meta name='viewport' content='width=device-width, height=device-height, initial-scale:1, user-scalable=no' />
            <title>Title Here</title>
            <link type='text/css' rel='stylesheet' href='css/external.css' />
            <script src='js/external.js'></script>
          </head>
        <body>
          <div class='main'>
            <div id='lister'>
              <input id='input_item' type='text' maxlength='239' /><input id='add_item' type='button' value='ADD' />
              <ul id='items'></ul>
              <div class='hid' id='control'><input class='warn' id='clear' type='button' value='CLEAR' /><input class='warn' id='reverse' type='button' value='REVERSE' /></div>
            </div>
          </div>
        </body>
        </html>

        当然,localStorage 必须在您的服务器(可能是本地主机)上进行测试,因为这是 Stack Overflow 上的一个问题。他们应该将虚拟 localStorage 和 sessionStorage 添加到此站点。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2022-08-09
          • 1970-01-01
          • 2023-04-08
          • 1970-01-01
          • 2021-02-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多