我有一个类别列表可通过HTML中的复选框选择。我的目标是让用户使用复选框选择他们想要的类别,并在他们返回时保存他们的选择。
我见过看起来简单的Jquery解决方案,但为此我不想使用Jquery。我可以让复选框选择保持一个会话,但是当我打开下一个会话时无法获得选择。
<input type="checkbox" class="chbox" value="animals"checked>
<label for="animals">Animals</label><br>
<input type="checkbox" class="chbox" value="city">
<label for="textures">City</label><br>
function checksValue() {
var checkedBoxes = document.getElementsByClassName('chbox');
var result = [];
for ( i = 0; i < 5; i++) {
if (checkedBoxes[i].checked === true) {
result += checkedBoxes[i].value + ", ";
}
}
localStorage.setItem("checkedBoxes", JSON.stringify(result));
假设这些复选框位于<form>
标记中:
- 获取reference to the form:
var main = document.forms[0];
- 下一个collect all of its form controls into a NodeList和convert it into an array:
Array.from(main.elements)
- 然后通过
map()
和check which ones are checked and which ones aren't:return chk.checked ? 1 : 0;
运行数组map()
返回一个数组(已选中)和零(未选中):var values = [0,1,0,0,1,1]
- Store认为array as a string在一把钥匙下进入
localStorage
(例如chx
):localStorage.setItem('chx', JSON.stringify(values));
- 创建一个IIFE:
!(function() {{...})()
- Get来自
localStorage
的密钥和convert it back into an array保存的字符串:var values = JSON.parse(localStorage.getItem('chx')) || [];
- 运行
forEach()
通过数组和数组中找到的每个1
,check the checkbox对应当前索引:m.elements[idx].setAttribute('checked', true);
注意:以下演示将不允许lobalStorage
工作,审查功能演示转到此Plunker。
var main = document.forms[0];
!(function(m) {
var values = JSON.parse(localStorage.getItem('chx')) || [];
values.forEach(function(val, idx) {
if (val === 1) {
m.elements[idx].setAttribute('checked', true);
}
});
})(main);
main.addEventListener('change', saveChx);
function saveChx(e) {
var chxArray = Array.from(main.elements);
var values = chxArray.map(function(chk) {
return chk.checked ? 1 : 0;
});
console.log(values);
return localStorage.setItem('chx', JSON.stringify(values));
}
<form id='main' onsubmit='return false'>
<input class='chx' type='checkbox'>
<input class='chx' type='checkbox'>
<input class='chx' type='checkbox'>
<input class='chx' type='checkbox'>
<input class='chx' type='checkbox'>
<input class='chx' type='checkbox'>
</form>
在这里,我看到三个步骤:
首先,让我们定义我们将保存和检索的数据结构,我认为这可能是一个很好的结果:
{
"animals": true | false,
"city": true | false,
...
}
现在,定义一个帮助方法来检索复选框的状态:
const LOCAL_STORAGE_KEY = 'my_checkboxes' // you can use your key here
const loadStatus = () =>
JSON.parse(localStorage.getItem(LOCAL_STORAGE_KEY)) || {}
这里没有什么特别的:解析从本地存储中检索的项目,如果之前没有保存状态,则返回一个空对象。
能够加载,我们需要能够保存:
const saveStatus = checkboxes => () => {
const status = checkboxes.reduce(
(map, checkbox) => Object.assign({}, map, { [checkbox.value]: checkbox.checked }),
{}
)
localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(status))
}
此方法采用一系列复选框并返回一个事件处理程序(用于复选框更改事件)。它基本上将值映射到它们的检查状态。
在window.onload
事件处理程序中将所有内容链接在一起应该可以解决您的问题:
window.onload = () => {
// retrieve checks from the local storage
const checks = loadStatus()
// for each key value pair...
Object.entries(checks).forEach(
([value, isChecked]) => {
// ...sets the check status
document.querySelector(`[value="${ value }"]`).checked = isChecked
}
)
// add event listener that update the local storage when a checkbox change its status
const checkboxes = Array.from(document.querySelectorAll('.chbox'))
checkboxes.forEach(
checkbox => checkbox.addEventListener('change', saveStatus(checkboxes))
)
}
我知道有些部分可能看起来很难,我很乐意帮助以防万一。
这就是你需要的。
请记住,我使用的是ES6,因此如果您需要使用旧版本的JS,则应该在旧版本中翻译代码。
// Select all the document elements with class .chbox
let cboxes = document.querySelectorAll('.chbox');
// Responsible to handle the user click on the selected checkboxes.
let handleCheckBoxEvent = function (e) {
// If the checkbox is checked
if (e.target.checked) {
// Then save the value in the local storage.
localStorage.setItem( e.target.value, e.target.checked );
} else {
// Else, if the checkbox is unchecked, remove the value from the local storage
localStorage.removeItem( e.target.value );
}
};
// If more than 0 checkboxes found
if ( 0 < cboxes.length ) {
// Iterate over the found elements
cboxes.forEach(
cb => {
// If the current iterated checkbox name exists in the local storage
if ( localStorage.getItem( cb.value ) ) {
// Add the checked property so the checkbox appears as checked.
cb.setAttribute('checked', 'checked');
}
// Add an event listener to the current iterated checkbox and bind it with the handleCheckBoxEvent function.
cb.addEventListener(
'change',
handleCheckBoxEvent
);
}
);
}
<input type="checkbox" class="chbox" value="animals">
<label for="animals">Animals</label><br>
<input type="checkbox" class="chbox" value="city">
<label for="textures">City</label><br>
另外,请记住,我的解决方案非常基本,因为它为localStorage中的每个选中的复选框引入了一个新密钥。对于每种情况,有许多实现都可能是正确的。