我有一个与调用resetForm() 函数的按钮关联的单击事件。此函数清除输入的值并清除实时存储值的 fields_entity session 。当检查resetForm函数内的日志时,发现 session 为空。但是,当更改 select 元素中的选项时,先前填充和清除的值将重新插入到已清除的输入中。 roleOption() 函数中的第二个 session 检查(在与 #role 关联的更改事件上调用)显示 fields_entity session 以及最后插入的值,就好像该 session 仍然存在一样。值得注意的是,所有这些都是在不重新加载页面的情况下完成的。我的问题是了解为什么会出现这种行为。我设法以某种方式解决了这个问题,但我真的很想了解为什么 fields_entity 仍然存在。我不确定自动保存功能中是否缺少某些内容。
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
</head>
<body>
<form class="form user">
<h2>Cadastrar <span></span></h2>
<label for="role">Choose your role</label>
<select id="role" name="role">
<option value="teacher" name="teacher">Teacher</option>
<option value="student" name="student">Student</option>
<option value="adm" name="adm">Collaborator</option>
</select>
<label for="name">Full name</label>
<input type="text" id="name" name="name">
<label for="email">Email</label>
<input type="email" id="email" name="email" novalidate>
<label for="password">Password</label>
<input type="password" id="password" name="password">
<div class="strength-pwd"></div>
<button type="submit">Register</button>
<button type="button" onclick="resetForm();"> Clear formulary</button>
</form>
<script>
function autosave(form, id) {
let fields = sessionStorage.getItem(`fields_${id}`);
fields ? (fields = JSON.parse(fields)) : (fields = {});
Array.from(form.elements).forEach(input => {
if (input.tagName === "INPUT" || input.tagName === "SELECT") {
input.addEventListener("input", () => {
fields[input.name] = input.value;
sessionStorage.setItem(`fields_${id}`, JSON.stringify(fields));
});
}
});
Object.keys(fields).forEach(key => {
const input = document.querySelector(`input[name="${key}"], select[name="${key}"]`);
if (input) {
input.value = fields[key];
}
});
}
const form = document.querySelector(".form.user");
const role = document.querySelector("#role");
function roleOptions() {
autosave(form, "entity"); //Second check = {name : ..., email...};
let roleValue = role.value;
switch (roleValue) {
case "student":
studentFormulary();
break;
case "teacher":
teacherFormulary();
break;
case "adm":
admFormulary();
break;
default:
studentFormulary();
break;
}
};
role.addEventListener("change", roleOptions);
function resetForm() {
form.querySelectorAll("input").forEach(e => { e.value = ""; });
sessionStorage.removeItem("fields_entity"); //First check = null
}
function studentFormulary() {
//...
}
function teacherFormulary() {
//...
}
function admFormulary() {
//...
}
roleOptions();
</script>
</body>
</html>
在这种情况下,我对找到此问题的解决方案不感兴趣,而是对了解其行为感兴趣。我试图识别它的所有方法都是使用 console.log 来观察值的存在,但我没有得出任何结论。
最佳答案
问题是您添加了 input
<input>
的事件监听器和<select>
更新 sessionStorage
的元素每当 autosave
中的字段发生变化时功能。 addEventListener
不会删除以前的事件监听器,因此每次 autosave
都会获得更多监听器被调用。
autosave
函数在 fields
上形成一个闭包变量,它只是从 sessionStorage
中获取的值在调用该函数时。即使清除了 sessionStorage,fields
仍然是同一个对象。
关于javascript - 为什么删除sessionStorage后仍然存在,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76695988/