Свойства объекта не изменяют значение элемента при помещении в localalstorage - PullRequest
1 голос
/ 04 ноября 2019

Я создал объект, который хранит коды клавиш для входов DOM. Первоначально для каждого ввода задается значение по умолчанию, сопоставленное с кодом клавиши, когда обновляется код клавиши, но значение ввода становится неопределенным. Почему это?

    const inputs = localStorage.keys ? JSON.parse(localStorage.keys) : [
       {elem: document.getElementById("x1split_input"), key: null},
       {elem: document.getElementById("x2split_input"), key: 81},
       {elem: document.getElementById("x16split_input"), key: 16},
       {elem: document.getElementById("respawn_input"), key: 82}
    ]

    for(let obj of inputs){
       obj.elem.value = keyboardMap[obj.key] 
       obj.elem.onkeyup = (key) => {
           obj.key = key.keyCode
           obj.elem.value = keyboardMap[obj.key] 
           localStorage.setItem("keys", JSON.stringify(inputs))
      }
    }
    console.log(localStorage.keys) 
    //[{"elem":{},"key":null},{"elem":{"value":"Q"},"key":81},{"elem":{"value":"SHIFT"},"key":16},{"elem":{"value":"A"},"key":65}]

1 Ответ

1 голос
/ 04 ноября 2019

Как только вы извлекаете сохраненный объект из области хранения, вы теряете элемент, на который указывал .elem каждого объекта. Все, что у вас есть, это простой объект, и добавление метода onkeyup к ним не будет таким же, как если бы они были фактическими элементами.

const inputs = [ { elem: document.getElementById("my-input") } ];
console.log( inputs ); // [ { "elem": <input id="my-input"> } ]

const in_storage = JSON.stringify( inputs );
console.log( in_storage ); // '[{"elem":{}}]'

const from_storage = JSON.parse( in_storage );
console.log( from_storage ); // [ { "elem": {} } ]
<input id="my-input">

Таким образом, вам действительно нужно извлекать элементы из документа каждый раз, когда вы будете извлекать свои объекты из StorageArea.

Для этого, вы можете использовать как функцию reviver, которую вы можете передать JSON.parse (string, reviver) , так и replacer , которую вы можете передать JSON.stringify (object, replacer) , так что вместо сохранения пустых объектов вы сохраняете только элемент id при строковом преобразовании, а вместо извлечения только этой строки вы получаете непосредственно элемент вразбор.

// used in JSON.parse
function reviver( key, value ) {
  if( key === "elem" ) {
    return document.getElementById( value );
  }
  return value;
}
// used in JSON.stringify
function replacer( key, value ) {
  if( key === "elem" ) {
    return value.id;
  }
  return value
}

// StackSnippets don't allow localStorage
// so let's make a fake one, already populated
const localStorage = {
  keys: `[
    {"elem":"x1split_input","key":null},
    {"elem":"x2split_input","key":81},
    {"elem":"x16split_input","key":16},
    {"elem":"respawn_input","key":82}
  ]`,
  setItem(key, val) {
    this[key] = val;
    console.log( 'saving', val );
  }
};
const keyboardMap = {81:'foo', 16:'bar', 82:'bla'};

btn.onclick = e => {
const inputs = localStorage.keys ? JSON.parse(localStorage.keys, reviver) : [
  // your initial object, not used in this demo
]

for (let obj of inputs) {
  obj.elem.value = keyboardMap[obj.key];
  obj.elem.onkeyup = (key) => {
    obj.key = key.keyCode;
    obj.elem.value = keyboardMap[obj.key];
    localStorage.setItem("keys", JSON.stringify(inputs, replacer))
  }
}
console.log(localStorage.keys)

}
<button id="btn">retrieve from (fake) localStorage</button><br>
<input id="x1split_input"><br>
<input id="x2split_input"><br>
<input id="x16split_input"><br>
<input id="respawn_input"><br>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...