为什么从表单输入保存到本地存储的字符串是空白的?

Why is a string that is saved to local storage from a form input blank?

我正在尝试制作一个在用户按下按钮时保存数据的表单。

   <form>
   <label for="name">Name:</label>
   <input type="text" id="name" name="name">
   <label for="age">Age:</label>
   <input type="text" id="age" name="age">
   <button type="button" onclick="SaveData()">Save Data</button>
   <button type="button" onclick="LoadData()">Load Data</button>
   </form>

这是我的尝试。当我尝试加载数据时,它只是空白。

var name = document.getElementById("name").value;
function SaveData() {
    localStorage.setItem("name", name);     
}
function LoadData() {
    var data = localStorage.getItem("name");
    alert(data);
}

您需要检查函数内的 #name 值。

function SaveData() {
  var name = document.getElementById("name").value;
  localStorage.setItem("name", name);     
}
  <form onsubmit="onSave()">
   <label for="name">Name:</label>
   <input type="text" id="name" name="name">
   <label for="age">Age:</label>
   <input type="text" id="age" name="age">
   <input type="submit" value="Save Data" />
   <button type="button" onclick="LoadData()">Load Data</button>
   </form>
function onSave(event){
    event.preventDefault();
    const { currentTarget } = event;
    const data = new FormData(currentTarget)
    Array.from(data.entries()).forEach(function([key, value]) {
      window.localStorage.setItem(key, value);
    })
}

  <form id="form">
   <label for="name">Name:</label>
   <input type="text" id="name" name="name">
   <label for="age">Age:</label>
   <input type="text" id="age" name="age">
   <button type="button" onclick="SaveData()">Save Data</button>
   <button type="button" onclick="LoadData()">Load Data</button>
   </form>
const form = document.getElementById("form")
function onSave(event){
    const data = new FormData(form)
    Array.from(data.entries()).forEach(function([key, value]) {
      window.localStorage.setItem(key, value);
    })
}

查看this了解更多信息

除了不是从 SaveData 函数中获取 name 的错误外,人们并不真的想将所有表单数据表单控件明智地保存为本地存储的键值。应该考虑把它全部存起来。

一种可行的方法是同时使用两个 FormData and JSON.stringify 以便在单个表单 related/specific 键下同时存储所有表单的活动数据。

// local storage mock due to SO blocking
// built-in `localStorage` by privacy settings.
const localStorage = {
  storage: new Map,
  setItem(key, value) {
    this.storage.set(key, value);
  },
  getItem(key) {
    return this.storage.get(key) ?? null;
  }
};

function saveData(evt) {
  evt.preventDefault();

  const elmForm = evt.currentTarget;
  const storageKey = elmForm.dataset.storableForm;

  const activeData = Object.fromEntries(
    Array.from(
      new FormData(elmForm).entries()
    )
  );
  localStorage.setItem(
    storageKey,
    JSON.stringify(activeData)
  );

  // debug logging.
  console.log({
    [storageKey]: localStorage.getItem(storageKey)
  });
}
function loadData(evt) {
  const elmForm = evt.currentTarget.form;
  const storageKey = elmForm.dataset.storableForm;

  const storageData = JSON.parse(
    localStorage.getItem(storageKey)
  );
  Object
    .entries(storageData ?? {})
    .forEach(([key, value]) => {
      elmForm.elements[key].value = value;
    });

  // debug logging.
  console.log({ storageData });
}

document
  .querySelectorAll('[data-storable-form]')
  .forEach(elmNode => {
    elmNode
      .addEventListener('submit', saveData);
    elmNode
     .querySelector('[data-load]')
     .addEventListener('click', loadData);
  });
body { margin: 0; zoom: .95; }
.as-console-wrapper { min-height: 85%!important; }
<form data-storable-form="form-data-A">
  <label for="name">Name:</label>
  <input type="text" id="name" name="name">

  <label for="age">Age:</label>
  <input type="text" id="age" name="age">

  <button type="submit">Save Data</button>

  <button type="reset" onclick="console.clear();">Clear Data</button>

  <button type="button" data-load>Load Data</button>
</form>

请注意 name 设置在 saveData() 之外并且从未更新。因此,每当 saveData() 被调用时,它总是存储 name 的原始值,它(因为表单输入没有默认值)是空字符串。因此,更准确地说,它正在加载默认值,而不是空白值。

要存储输入的当前值,您需要在每次调用 saveData() 之前更新 name 或直接在 saveData() 中访问该值。由于有多个输入,您需要为每个输入执行此操作。一个简单的解决方案是将表单传递给 saveData() 并让它检查 each of the inputs in the form:

function saveData(form) {
    for (elt of form.elements) {
        if (elt.id || elt.name) {
            localStorage.setItem(elt.id || elt.name, elt.value);
        }
    }
}

“保存”表单按钮将更新为:

<button type="button" onclick="SaveData(this.form)">Save Data</button>

您可以对 LoadData() 和“加载”按钮进行类似的更改。

除了从 onclick 属性调用数据保存和加载函数外,您还可以在此处使用 addEventListener (which has certain advantages, as outlined both in the linked MDN document and "addEventListener vs onclick",但传递表单的处理方式不同。