本地存储和JSON序列化及反序列化

12

我一直在开发一个项目,允许用户提交关于他们访问过的地方的记忆,并跟踪提交记忆时的位置。我的唯一问题是尝试在应用程序中使用localStorage,我阅读了有关JSON.stringify和JSON.parse的内容,但还不知道如何在我的代码中使用它们。

这是我的form.js,它处理表单并获取文本字段。当单击“添加”按钮(在显示详细信息页面上)或单击“输入详细信息”按钮时,它会清除表单。最后,它接收信息并将消息发送回窗口。

function processForm(){

var locate = document.myform.locate.value;
var details = document.myform.details.value;
var storeData = []; 
localStorage.setItem("locate", JSON.stringify(locate));
localStorage.setItem("details", JSON.stringify(details));
alert("Saved: " + localStorage.getItem("locate") + ", and " + localStorage.getItem("details"));

var date = new Date,
    day = date.getDate(),
    month = date.getMonth() + 1,
    year = date.getFullYear(),
    hour = date.getHours(),
    minute = date.getMinutes(),
    ampm = hour > 12 ? "PM" : "AM";    
    hour = hour % 12;
    hour = hour ? hour : 12; // zero = 12
    minute = minute > 9 ? minute : "0" + minute;
    hour = hour > 9 ? hour : "0" + hour;

    date = month + "/" + day + "/" + year + " " + hour + ":" + minute +  " " + ampm;

localStorage.setItem("date", JSON.stringify(date));

storeData.push(locate, details, date);
localStorage.setItem("storeData", JSON.stringify(storeData));   
}

function clearForm(){
$('#myform').get(0).reset();
}

function retrieveFormInfo(){

var data = JSON.parse(localStorage.getItem("storeData"));   

var locate = JSON.parse(localStorage.getItem("locate"));
$("#locate2").html("Place: " + locate);

var details = JSON.parse(localStorage.getItem("details"));
$("#details2").html("Description: " + details);

var date = JSON.parse(localStorage.getItem("date"));
$("#date").html(date);

}
但是我遇到的主要问题是,我不知道如何使用JSON.stringify和JSON.parse正确地获取这些信息,并将其动态地附加到带有HTML元素的窗口中,主要是像记忆列表一样。任何帮助都将不胜感激!

下次请在此处发布相关代码 - 请参考http://www.sscce.org/以了解如何从您的代码中创建有用的示例。您已经在代码中设置了一个数组 - storeData = [],并向其中添加了元素 - storeData.push()。但您可能想要使用对象,因为您希望为添加的每个值命名 - 例如日期、小时、分钟。您可以通过创建一个对象 - store = {},然后向其添加属性 - store['date'] = ...来实现这一点。 - Sacho
4个回答

29

localStorage仅将键值对存储为字符串(您可以使用整数作为键,但它们会自动转换为字符串)。

存储对象是简单的键-值存储,类似于对象,但在页面加载时保持不变。键和值总是字符串(请注意,与对象一样,整数键将自动转换为字符串)参考

假设您有一个要存储的数组,其中每个项都是JSON对象。

您有两个选项:

选项1:

  • stringify每个项并存储在localStorage中

var item = {input1: 'input1value', input2: 'input2value' };
localStorage.setItem( itemIndex, JSON.stringify(item) );
  • 要检索项目,请遍历localStorage项目,然后将该项目转换为JSON对象:
for(var i=0;i<localStorage.length; i++) {
  var key = localStorage.key( i );
  var item = JSON.parse( localStorage.getItem( key ) );
}

选项2:

  • 将整个数组转化为字符串并存储在localStorage中

localStorage.setItem( 'memoriesdata', JSON.stringify( arr ) );
  • 读取数据时,请将项目作为字符串读取,然后转换为JSON对象。

  • var arr = JSON.parse( localStorage.getItem('memoriesdata') );
    

    谢谢!上次的方法非常有用! - Jorge Guerra Pires
    不,键是字符串。如果您使用整数(或布尔值或其他任何内容)作为键,则会将其转换为字符串。 - T.J. Crowder
    @T.J.Crowder,你是正确的。看起来参考页面的文本已经更新了。我也更新了我的答案文本,以避免任何混淆。 - gp.

    5

    首先将输入字段的值获取到一个JavaScript对象中。

    var myMemory = {};
    myMemory.location = document.getElementById('location').value;
    myMemory.description = document.getElementById('description').value;
    

    现在将myMemory保存到localStorage中,这可以在表单提交或按钮按下时完成。我们可以将其存储为记忆的数组,并每次添加项目。

    //if user already has memories in local, get that array and push into it.
    //else create a blank array and add the memory.
    memories = localStorage.getItem('memories') ?
                  JSON.parse(localStorage.getItem('memories')) : 
                  [];
    memories.push(myMemory);
    localStorage.setItem('memories', JSON.stringify(memories));
    

    3

    我使用这个Storage实现。它受到许多存储插件的启发...它可以处理由JSON.stringify函数序列化的任何值,并且应该在跨浏览器(以及在“禁用cookie”的Firefox中)上工作:

    //
    //    api:
    //
    // .clear()    empties storage
    // .each()     loops storage (key, value) pairs
    // .fetch()    get a value by key
    // .has()      checks if there is a key set
    // .ls()       lists all keys 
    // .raw()      string value actually stored
    // .reload()   reads in serialized data
    // .rm()       removes key(s)
    // .set()      setup value(s)
    // .type()     storage type used 'localStorage/globalStorage/userData'
    // .valid()    is storage engine setup correctly
    //
    ;
    ((function(name, def, glob, doc) {
    
      // add 'store' id to globals
      this[name] = def(glob, doc);
    }).call(
      this, "store", function(glob, doc) {
    
        // private (function) store version
        var stclient;
    
        var driver = {
          // obj  : storage_native{},
          // type : storage_type
        };
    
        var engine = {
          // read  : (func),
          // write : (func)
        };
    
        var _ = {
    
          a: Array.prototype,
          del: function(node) { // , ...fields
    
            _.slc(arguments, 1).
            forEach(function(field) {
              delete this[field];
            }, node);
    
            return node;
          },
          each: function(array, callback, context) {
    
            context ||
              (context = array);
    
            array.
            some(function() {
              return false === callback.apply(context, arguments);
            });
    
            return array;
          },
          hasown: Function.prototype.call.bind(Object.prototype.hasOwnProperty),
          jsdc: JSON.parse, // decode
          jsec: JSON.stringify, // encode 
          keys: Object.keys, // shimed .keys
          ns: "storage5", // single property name to keep serialized storage data under
          object: null, // parsed storage data 
          slc: Function.prototype.call.bind(Array.prototype.slice),
          test: {
    
            isemptyobj: function(node) {
              for (var x in node)
                return false;
              return true;
            },
    
            isplainobj: function(node) {
              return '[object Object]' == Object.prototype.toString.call(node);
            },
    
          },
          testval: 'storage' + Math.random(), // test value for implementation check
          rig: function(target, items) {
    
            for (var field in items)
              if (items.hasOwnProperty(field))
                target[field] = items[field];
    
            return target;
          },
          clone: function(node) {
            return _.jsdc(_.jsec(node));
          },
          puts: function() {
            engine.write(_.jsec(_.object));
          },
        };
    
        stclient = function storage5() {
          return arguments.length ?
            storage5.set.apply(storage5, arguments) :
            storage5.fetch();
        };
    
        // _init on load|ready
        window.addEventListener('load', _init, false);
    
        return _.rig(stclient, {
    
          clear: function() {
            return _.object = {}, _.puts(), this;
          },
    
          each: function(callback, context) {
    
            context ||
              (context = this.fetch());
    
            _.each(this.ls(), function(field) {
              return callback.call(context, field, this.fetch(field));
            }, this);
    
            return this;
          },
    
          fetch: function(key) {
            return (arguments.length) ?
              _.object[key] : _.clone(_.object);
          },
    
          has: function(name) {
            return _.hasown(_.object, name);
          },
    
          ls: function() {
            return _.keys(_.object);
          },
    
          raw: function() {
            return engine.read();
          },
    
          reload: _load,
    
          rm: function() {
    
            _.del.apply(null, _.a.concat.apply([_.object], arguments));
    
            return _.puts(), this;
          },
    
          set: function(input, value) {
    
            var len = arguments.length;
            var flag = 1;
    
            if (len) {
    
              if (_.test.isplainobj(input)) {
    
                _.keys(input).
                forEach(function(field) {
                  _.object[field] = input[field];
                });
    
              } else {
    
                if (1 < len)
                  _.object[input] = value;
                else
                  flag = 0;
    
              }
    
              flag && _.puts();
    
            }
    
            return this;
          },
    
          type: function() {
            return driver.type || null;
          },
    
          valid: function() {
            return !_.test.isemptyobj(driver);
          },
    
        });
    
        function _init() {
    
          var flag = 0;
          var stnative;
    
          if ("localStorage" in glob) {
            try {
              if ((stnative = glob["localStorage"])) {
                // inits localStorage 
                _initlocst(stnative, driver, engine);
                flag = 1;
              }
            } catch (e) {}
          }
    
          if (!flag) {
    
            if ("globalStorage" in glob) {
              try {
                if ((stnative = glob["globalStorage"])) {
                  // inits globalStorage
                  _initglobst(stnative, driver, engine);
                  flag = 1;
                }
              } catch (e) {}
            }
    
            if (!flag) {
              // inits userDataStorage
              _initusrdatast(doc.createElement(_.ns), driver, engine);
            }
          }
    
          // parse serialized storage data
          _load();
        }
    
        function _initlocst(stnative, driver, engine) {
    
          stnative[_.testval] = _.testval;
    
          if (_.testval === stnative[_.testval]) {
    
            try {
              stnative.removeItem(_.testval);
            } catch (e) {
              try {
                delete stnative[_.testval];
              } catch (e) {}
            }
    
            driver.obj = stnative;
            driver.type = "localStorage";
    
            engine.read = function() {
              return driver.obj[_.ns];
            };
    
            engine.write = function(stringvalue) {
              driver.obj[_.ns] = stringvalue;
              return stringvalue;
            };
    
          }
        }
    
        function _initglobst(stnative, driver, engine) {
    
          var host = glob.location.hostname;
    
          driver.obj = (/localhost/i).test(host) ?
            stnative["localhost.localdomain"] : stnative[host];
    
          driver.type = "globalStorage";
    
          engine.read = function() {
            return driver.obj[_.ns];
          };
    
          engine.write = function(stringvalue) {
            driver.obj[_.ns] = stringvalue;
            return stringvalue;
          };
    
        }
    
        function _initusrdatast(node, driver, engine) {
    
          try {
    
            node.id = _.ns;
            node.style.display = "none";
            node.style.behavior = "url('#default#userData')";
    
            doc.
            getElementsByTagName("head")[0].
            appendChild(node);
    
            node.load(_.ns);
    
            node.setAttribute(_.testval, _.testval);
            node.save(_.ns);
    
            if (_.testval === node.getAttribute(_.testval)) {
    
              try {
    
                node.removeAttribute(_.testval);
                node.save(_.ns);
    
              } catch (e) {}
    
              driver.obj = node;
              driver.type = "userData";
    
              engine.read = function() {
                return driver.obj.getAttribute(_.ns);
              };
    
              engine.write = function(stringvalue) {
                driver.obj.setAttribute(_.ns, stringvalue);
                driver.obj.save(_.ns);
                return stringvalue;
              };
    
            }
    
          } catch (e) {
            doc.
            getElementsByTagName("head")[0].
            removeChild(node);
          }
    
          node = null;
        }
    
        function _load() {
    
          try {
            _.object = _.jsdc((engine.read() || engine.write("{}")));
          } catch (e) {
            _.object = {};
          }
        }
    
      }, window, document));
    
      //eof
    

    2

    Vanilla JS:

    var printStorageBody = function () {
        var body = document.querySelector("body");
        var pre = document.createElement("pre");
        body.innerHTML = "";
        pre.innerText = JSON.stringify(localStorage, null, '\t');
        body.appendChild(pre);
    }
    

    jQuery:

    var printStorageBody = function () {
        $("body").html("");
        $("<pre>")
        .text(JSON.stringify(localStorage, null, '\t'))
        .appendTo("body");
    }
    

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接