我创建了一个对象,该对象存储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}]
答案 0 :(得分:1)
一旦从“存储”区域检索了存储的对象,您将丢失每个对象的.elem
所指向的Element。您所拥有的只是一个普通对象,并且在这些对象上添加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中检索对象时,您实际上都需要从文档中检索元素。
为此,您可以同时使用可以传递给JSON.parse( string, reviver )的reviver函数和可以传递给JSON.stringify( object, replacer )的 replacer ,这样就不必保存空白对象,则在字符串化时只保存Element的id
,而不是仅检索此字符串,而是在解析时直接获得Element。
// 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>