Javascript SortableJS不是';t在本地存储中保存已排序的待办事项列表
我有一个带有localStorage和SortableJS的todo项目。我遇到了这样的问题:当我对待办事项列表排序时,它不会更新本地存储。有人能帮我找出一种保存已排序列表的方法吗?下面是代码,但如果您能访问代码段下的codepen链接,那就太好了Javascript SortableJS不是';t在本地存储中保存已排序的待办事项列表,javascript,html,sortablejs,Javascript,Html,Sortablejs,我有一个带有localStorage和SortableJS的todo项目。我遇到了这样的问题:当我对待办事项列表排序时,它不会更新本地存储。有人能帮我找出一种保存已排序列表的方法吗?下面是代码,但如果您能访问代码段下的codepen链接,那就太好了 const clear=document.querySelector(“.clear”); const dateElement=document.getElementById(“日期”); const list=document.getElemen
const clear=document.querySelector(“.clear”);
const dateElement=document.getElementById(“日期”);
const list=document.getElementById(“列表”);
常量输入=document.getElementById(“输入”);
//类名
const CHECK=“fa检查圆”;
const UNCHECK=“fa circle thin”;
const LINE_THROUGH=“lineThrough”;
//变数
let LIST,id;
//从本地存储获取项目
让data=localStorage.getItem(“TODO”);
//检查数据是否为空
如果(数据){
LIST=JSON.parse(数据);
id=LIST.length;
装载清单(清单);
}否则{
列表=[];
id=0;
}
//将项目加载到用户界面
函数加载列表(数组){
array.forEach(函数(项){
addToDo(item.name、item.id、item.done、item.trash);
});
}
//清除本地存储
clear.addEventListener(“单击”,函数(){
localStorage.clear();
location.reload();
})
//显示今天的日期
常量选项={
工作日:“长”,
月:“短”,
日期:“数字”
};
const today=新日期();
dateElement.innerHTML=today.toLocaleDateString(“en-US”,选项);
//添加待办事项功能
函数addToDo(toDo、id、done、trash){
如果(垃圾){
返回;
}
const DONE=DONE?勾选:取消勾选;
常量行=完成?行_到:“”;
const item=`
${toDo}
`;
const position=“beforeend”;
列表.插入附件TML(位置,项目);
}
//当用户单击enter键时,向列表中添加一项
文件。添加事件列表器(“键控”,功能(事件){
如果(event.keyCode==13){
const toDo=input.value;
//如果输入不是空的
如果(待办事项){
addToDo(toDo);
LIST.push({
姓名:toDo,
id:id,
完成:错误,
垃圾:错
});
//将项添加到本地存储
setItem(“TODO”,JSON.stringify(LIST));
id++;
}
input.value=“”
}
});
//完成
函数completeToDo(元素){
element.classList.toggle(检查);
element.classList.toggle(取消选中);
element.parentNode.querySelector(“.text”).classList.toggle(第_行至第);
LIST[element.id].done=LIST[element.id].done?false:true;
}
//撤职
函数removeToDo(元素){
element.parentNode.parentNode.removeChild(element.parentNode);
LIST[element.id].trash=true;
//将项添加到本地存储
setItem(“TODO”,JSON.stringify(LIST));
}
//以动态创建的项目为目标
list.addEventListener(“单击”),函数(事件){
常量元素=event.target;
const elementJob=element.attributes.job.value;
如果(elementJob==“完成”){
复合物(元素);
}else if(elementJob==“删除”){
移除(元素);
}
//将项添加到本地存储
setItem(“TODO”,JSON.stringify(LIST));
});
//用于对列表进行排序
可排序。创建(列表{
动画:100,
组:“列表-1”,
可拖动:“#列出li”,
句柄:“#列表li”,
排序:对,
筛选器:'.sortable已禁用',
chosenClass:“活动”
});代码>
/*-----------youtube.com/code解释--------*/
身体{
填充:0;
保证金:0;
背景色:rgba(0,0,0,0.1);
字体系列:“titilliumweb”,无衬线;
}
/*------容器------------*/
.集装箱{
填充:10px;
宽度:380px;
保证金:0自动;
}
/*------标题------------*/
.标题{
宽度:380px;
高度:200px;
背景图像:url(“”);
背景大小:100%200%;
背景重复:无重复;
边界半径:15px 15px 0;
位置:相对位置;
}
.清楚{
宽度:30px;
高度:30px;
位置:绝对位置;
右:20px;
顶部:20px;
}
.clear i{
字体大小:30px;
颜色:#FFF;
}
.清除i:悬停{
光标:指针;
文本阴影:1px 3px 5px#000;
变换:旋转(45度);
}
#日期{
位置:绝对位置;
底部:10px;
左:10px;
颜色:#FFF;
字体大小:25px;
字体系列:“titilliumweb”,无衬线;
}
/*------内容------------*/
.内容{
宽度:380px;
高度:350px;
最大高度:350px;
背景色:#FFF;
溢出:自动;
}
.content::-webkit滚动条{
显示:无;
}
.内容ul{
填充:0;
保证金:0;
}
.项目{
宽度:380px;
高度:45px;
最小高度:45px;
位置:相对位置;
边框底部:1px实心rgba(0,0,0,0.1);
列表样式:无;
填充:0;
保证金:0;
}
.第一项{
位置:绝对位置;
字体大小:25px;
左侧填充:5px;
左:15px;
顶部:10px;
}
.项目i.co:悬停{
光标:指针;
}
.fa检查圈{
颜色:#6eb200;
}
.项目p.文本{
位置:绝对位置;
填充:0;
保证金:0;
字体大小:20px;
左:50px;
顶部:5px;
背景色:#FFF;
最大宽度:285px;
}
.lineThrough{
文字装饰:线条贯通;
颜色:#ccc;
}
.第一项{
位置:绝对位置;
字体大小:25px;
右:15px;
顶部:10px;
}
.项目i.de:悬停{
颜色:#af0000;
光标:指针;
}
/*------添加项目------------*/
.添加{
位置:相对位置;
宽度:360px;
高度:40px;
背景色:#FFF;
填充:10px;
边框顶部:1px实心rgba(0,0,0,0.1);
}
.加上{
位置:绝对位置;
字体大小:40px;
颜色:#4162f6;
}
.添加待办事项输入{
位置:绝对位置;
左:50px;
高度:35px;
宽度:310px;
背景色:透明;
边界:无;
字体大小:20px;
左侧填充:10px;
}
.add to do输入:--webkit输入占位符{
/*Chrome/Opera/Safari*/
颜色:#4162f6;
字体系列:“titilliumweb”,无衬线;
字体大小:20px;
}
.添加待办事项输入:-moz占位符{
/*Firefox 19+*/
颜色:#4162f6;
字体系列:“titilliumweb”,无衬线;
字体大小
const clear = document.querySelector(".clear");
const dateElement = document.getElementById("date");
const list = document.getElementById("list");
const input = document.getElementById("input");
// Class names
const CHECK = "fa-check-circle";
const UNCHECK = "fa-circle-thin";
const LINE_THROUGH = "lineThrough";
// Variables
let LIST, id;
// Get item from localStorage
let data = localStorage.getItem("TODO");
// Check if data is not empty
if(data) {
LIST = JSON.parse(data);
id = LIST.length;
loadList(LIST);
}else{
LIST =[];
id = 0;
}
// Load items to the user's interface
function loadList(array) {
array.forEach(function(item){
addToDo(item.name, item.id, item.done, item.trash);
});
}
// Clear the localStorage
clear.addEventListener("click", function() {
localStorage.clear();
location.reload();
})
// Show today's date
const options = {weekday : "long", month : "short", day : "numeric"};
const today = new Date();
dateElement.innerHTML = today.toLocaleDateString("en-US", options);
// Add to do function
function addToDo(toDo, id, done, trash) {
if(trash) { return; }
const DONE = done ? CHECK : UNCHECK;
const LINE = done ? LINE_THROUGH : "";
const item = `<li class="item">
<i class="fa ${DONE}" job="complete" id="${id}"></i>
<p class="text ${LINE}">${toDo}</p>
<i class="fa fa-trash-o de" job="delete" id="${id}"></i>
</li>
`;
const position = "beforeend";
list.insertAdjacentHTML(position, item);
}
// Add an item to the list when the user cick the enter key
document.addEventListener("keyup", function(event) {
if(event.keyCode == 13) {
const toDo = input.value;
// If the input isn't empty
if(toDo) {
addToDo(toDo);
LIST.push({
name : toDo,
id : id,
done : false,
trash : false
});
// Add item to localStorage
localStorage.setItem("TODO", JSON.stringify(LIST));
id++;
}
input.value = ""
}
});
// complete to do
function completeToDo(element) {
element.classList.toggle(CHECK);
element.classList.toggle(UNCHECK);
element.parentNode.querySelector(".text").classList.toggle(LINE_THROUGH);
LIST[element.id].done = LIST[element.id].done ? false : true;
}
// Remove to do
function removeToDo(element) {
element.parentNode.parentNode.removeChild(element.parentNode);
LIST[element.id].trash = true;
// Add item to localStorage
localStorage.setItem("TODO", JSON.stringify(LIST));
}
// Target the items created dynamically
list.addEventListener("click", function(event) {
const element = event.target;
const elementJob = element.attributes.job.value;
if(elementJob == "complete") {
completeToDo(element);
}else if(elementJob == "delete"){
removeToDo(element);
}
// Add item to localStorage
localStorage.setItem("TODO", JSON.stringify(LIST));
});
function swapArrayElements(arr, indexA, indexB) {
var temp = arr[indexA];
arr[indexA] = arr[indexB];
arr[indexB] = temp;
};
function orderList(oldIndex, newIndex) {
swapArrayElements(LIST, oldIndex, newIndex)
localStorage.setItem("TODO", JSON.stringify(LIST));
}
// For sorting the list
Sortable.create(list, {
animation: 100,
group: 'list-1',
draggable: '#list li',
handle: '#list li',
sort: true,
filter: '.sortable-disabled',
chosenClass: 'active',
onSort: function (/**Event*/evt) {
orderList(evt.oldIndex, evt.newIndex);
},
});
Sortable.create(list, {
animation: 100,
group: 'list-1',
draggable: '#list li',
handle: '#list li',
sort: true,
filter: '.sortable-disabled',
chosenClass: 'active'
});
Sortable.create(list, {
store: {
//Get the order of elements. Called once during initialization.
// @param {Sortable} sortable
// @returns {Array}
get: function (sortable) {
var order = localStorage.getItem(sortable.options.group.name);
return order ? order.split('|') : [];
},
// Save the order of elements.
// @param {Sortable} sortable
set: function (sortable) {
var order = sortable.toArray();
localStorage.setItem(sortable.options.group.name, order.join('|'));
}
},
...rest of your options
});
var mySortable = Sortable.create(list, {...your options});
Sortable.create(list, {
group: "TODO2",
options: {
animation: 100,
draggable: "#list li",
handle: "#list li",
sort: true,
filter: ".sortable-disabled",
chosenClass: "active"
},
store: {
/**
* Get the order of elements. Called once during initialization.
* @param {Sortable} sortable
* @returns {Array}
*/
get: function(sortable) {
var order = localStorage.getItem(sortable.options.group.name);
return order ? order.split("|") : [];
},
/**
* Save the order of elements. Called onEnd (when the item is dropped).
* @param {Sortable} sortable
*/
set: function(sortable) {
var order = sortable.toArray();
localStorage.setItem(sortable.options.group.name, order.join("|"));
}
}
});
// For sorting the list
Sortable.create(list, {
animation: 100,
group: 'list-1',
draggable: '#list li',
handle: '#list li',
sort: true,
filter: '.sortable-disabled',
chosenClass: 'active',
onSort: function(e) {
var items = e.to.children;
var result = [];
for (var i = 0; i < items.length; i++) {
result.push(items[i].id);
}
var lsBefore = JSON.parse(localStorage.getItem("TODO"));
var lsAfter = [];
for (var i = 0; i < result.length; i++) {
var found = false;
for (var j = 0; j < lsBefore.length && !found; j++) {
if (lsBefore[j].id == result[i]) {
lsAfter.push(lsBefore[j]);
lsBefore.splice(j, 1);
found = true;
}
}
}
localStorage.setItem("TODO", JSON.stringify(lsAfter));
console.log(result);
console.log(lsBefore);
console.log(lsAfter);
}
const item = `<li class="item" id="${id}">
<i class="fa ${DONE}" job="complete" id="${id}"></i>
<p class="text ${LINE}">${toDo}</p>
<i class="fa fa-trash-o de" job="delete" id="${id}"></i>
</li>
`;