JavaScript 中的待办事项列表 - 删除任务后,您无法正确选择另一个任务



这是我的第一个大项目,我正在制定一个待办事项列表,到目前为止一切都很顺利,但我只是注意到了一个非常令人不快的问题。因此,我决定选择通过点击来编辑任务-你可以选择上下移动、重命名甚至删除它。我测试了删除功能,结果发现它没有按预期工作。当我第一次想删除任务时,一切都很好。这是待办事项列表。让我们删除任务"d"单击任务后,将打开此菜单:让我们点击"删除"瞧!任务没有了。让我们移除另一个。喜欢例如,下一个。让我们点击任务"f"然而,正如你所看到的。。。选择"g"任务而不是"f"。总之,在删除一个任务后,再次尝试删除任务会导致无法正确选择所需的任务。您不处理选定的任务,而是处理它之后的任务。为什么会发生这种情况?感谢您的帮助!提前感谢!

var everyTask = document.querySelectorAll('.regTask');
for (var q = 0; q < everyTask.length; q++) {  
everyTask[q].addEventListener('click', ((h) => {          
return function() {
rememberThisTaskValue = h;
}
})(q))
}
var allTasks = document.getElementsByClassName('regTask'); 
for (var b = 0; b < allTasks.length; b++) {
allTasks[b].onclick = function() {
document.getElementsByClassName('regTask')[rememberThisTaskValue].style.background = 'rgb(255, 255, 255)';
document.getElementsByClassName('regTask')[rememberThisTaskValue].onmouseover = function() {
this.style.background = 'rgb(255, 255, 255)';
}
document.getElementsByClassName('regTask')[rememberThisTaskValue].onmouseout = function() {
this.style.background = 'rgb(255, 255, 255)';
}
alert(rememberThisTaskValue);
temporaryLayer.style.animation = 'layerFadeIn 0.18s forwards';
temporaryLayer.style.background = 'rgba(0, 0, 0, 0.5)';
temporaryLayer.style.backdropFilter = 'blur(6px)';
body.appendChild(temporaryLayer);
var editor = document.createElement('div');
var editorTitle = document.createElement('h1');
var editorTitleNode = document.createTextNode('Edit task');
var editorSubTitle = document.createElement('h2');
// Styling
var editorSubTitleTextNodeContent = document.getElementsByClassName('regTask')[rememberThisTaskValue].innerHTML;
var editorSubTitleNode = document.createTextNode(editorSubTitleTextNodeContent);
var editorOptions = document.createElement('div');
var editorOptionsInput = document.createElement('input');
var editorOptionsDelete = document.createElement('button');
var editorOptionsDeleteNode = document.createTextNode('Delete');
var editorOptionsMove = document.createElement('button');
var editorOptionsMoveNode = document.createTextNode('Move');
var editorOptionsRename = document.createElement('button');
var editorOptionsRenameNode = document.createTextNode('Rename');
var editorOptionsCancel = document.createElement('button');
var editorOptionsCancelNode = document.createTextNode('Cancel');
// Styling
temporaryLayer.appendChild(editor);
editor.appendChild(editorTitle);
editorTitle.appendChild(editorTitleNode);
editor.appendChild(editorSubTitle);
editorSubTitle.appendChild(editorSubTitleNode);
editor.appendChild(editorOptions);
editorOptions.appendChild(editorOptionsRename);
editorOptionsRename.appendChild(editorOptionsRenameNode);
editorOptions.appendChild(editorOptionsMove);
editorOptionsMove.appendChild(editorOptionsMoveNode);
editorOptions.appendChild(editorOptionsDelete);
editorOptionsDelete.appendChild(editorOptionsDeleteNode);
editorOptions.appendChild(editorOptionsCancel);
editorOptionsCancel.appendChild(editorOptionsCancelNode);
editorOptionsCancel.onclick = function() {
// There is some styling here too but I am going to leave it just in case
editor.style.animation = 'editorFadeOut 0.18s forwards';
temporaryLayer.style.animation = 'layerFadeOut 0.18s forwards';
setTimeout (function() {
temporaryLayer.style.animation = 'none';
temporaryLayer.style.background = 'none';
temporaryLayer.style.backdropFilter = 'none';
editor.remove();
temporaryLayer.remove();
document.getElementsByClassName('regTask')[rememberThisTaskValue].style.background = 'rgba(255, 255, 255, 0.7)';
document.getElementsByClassName('regTask')[rememberThisTaskValue].onmouseover = function() {
this.style.background = 'rgb(255, 255, 255)';
}
document.getElementsByClassName('regTask')[rememberThisTaskValue].onmouseout = function() {
this.style.background = 'rgba(255, 255, 255, 0.7)';
}
}, 180)
}
editorOptionsDelete.onclick = function() {
// This is the function that deletes a task
document.getElementsByClassName('regTask')[rememberThisTaskValue].remove();
var everyTask = document.querySelectorAll('.regTask');
for (var q = 0; q < everyTask.length; q++) {  
everyTask[q].addEventListener('click', ((h) => {          
return function() {
var rememberThisTaskValue = h;
}
})(q))
}
editor.style.animation = 'editorFadeOut 0.18s forwards';
temporaryLayer.style.animation = 'layerFadeOut 0.18s forwards';
setTimeout (function() {
temporaryLayer.style.animation = 'none';
temporaryLayer.style.background = 'none';
temporaryLayer.style.backdropFilter = 'none';
editor.remove();
temporaryLayer.remove();
}, 180)
}
editorOptionsRename.onclick = function() {
editor.style.animation = 'editorFadeOut 0.18s forwards';
setTimeout (function() {
editor.remove();
}, 180)  
var nameChanger = document.createElement('div');
nameChanger.style.opacity = '0';
nameChanger.style.animation = "renameFadeIn 0.18s forwards";
var nameChangerTitle = document.createElement('h1');
var nameChangerTitleNode = document.createTextNode('Rename Task');
var nameChangerForm = document.createElement('form');
var nameChangerFormInput = document.createElement('input');
var nameChangerFormSubmit = document.createElement('button');
var nameChangerFormSubmitNode = document.createTextNode('Rename');
var nameChangerFormCancel = document.createElement('button');
var nameChangerFormCancelNode = document.createTextNode('Cancel');
// Styling
temporaryLayer.appendChild(nameChanger);
nameChanger.appendChild(nameChangerTitle);
nameChangerTitle.appendChild(nameChangerTitleNode);
nameChanger.appendChild(nameChangerForm);
nameChangerForm.appendChild(nameChangerFormInput);
nameChangerForm.appendChild(nameChangerFormSubmit);
nameChangerFormSubmit.appendChild(nameChangerFormSubmitNode);
nameChangerForm.appendChild(nameChangerFormCancel);
nameChangerFormCancel.appendChild(nameChangerFormCancelNode);
document.getElementById('taskRenameField').focus();
nameChangerFormCancel.onclick = function() {
event.preventDefault();
nameChanger.style.opacity = '1';
nameChanger.style.animation = 'changerFadeOut 0.18s forwards';
temporaryLayer.style.animation = 'layerFadeOut 0.18s forwards';
setTimeout (function() {
temporaryLayer.style.animation = 'none';
temporaryLayer.style.background = 'none';
temporaryLayer.style.backdropFilter = 'none';
nameChanger.remove();
temporaryLayer.remove();
document.getElementsByClassName('regTask')[rememberThisTaskValue].style.background = 'rgba(255, 255, 255, 0.7)';
document.getElementsByClassName('regTask')[rememberThisTaskValue].onmouseover = function() {
this.style.background = 'rgb(255, 255, 255)';
}
document.getElementsByClassName('regTask')[rememberThisTaskValue].onmouseout = function() {
this.style.background = 'rgba(255, 255, 255, 0.7)';
}
}, 180)
}
nameChangerFormSubmit.onclick = function() {
event.preventDefault();
if (!(nameChangerFormInput.value === "" || (!nameChangerFormInput.value.replace(/s/g, '').length))) {
var taskReminder = nameChangerFormInput.value.replace(/s+/g, " ").trim();
document.getElementsByClassName('regTask')[rememberThisTaskValue].innerHTML = taskReminder;
nameChanger.style.opacity = '1';
nameChanger.style.animation = 'changerFadeOut 0.18s forwards';
temporaryLayer.style.animation = 'layerFadeOut 0.18s forwards';
setTimeout (function() {
temporaryLayer.style.animation = 'none';
temporaryLayer.style.background = 'none';
temporaryLayer.style.backdropFilter = 'none';
nameChanger.remove();
temporaryLayer.remove();
document.getElementsByClassName('regTask')[rememberThisTaskValue].style.background = 'rgba(255, 255, 255, 0.7)';
document.getElementsByClassName('regTask')[rememberThisTaskValue].onmouseover = function() {
this.style.background = 'rgb(255, 255, 255)';
}
document.getElementsByClassName('regTask')[rememberThisTaskValue].onmouseout = function() {
this.style.background = 'rgba(255, 255, 255, 0.7)';
}
}, 180)
}
}
}
editorOptionsMove.onclick = function() {
// This is the function that lets the user move elements but it's still unfinished, I barely started it
editor.style.animation = 'editorFadeOut 0.18s forwards';
temporaryLayer.style.animation = 'layerFadeOut 0.18s forwards';
stipText.style.animation = 'tipFadeOut 0.18s forwards';
setTimeout (function() {
temporaryLayer.style.animation = 'none';
temporaryLayer.style.background = 'none';
temporaryLayer.style.backdropFilter = 'none';
editor.remove();
temporaryLayer.remove();
document.getElementsByClassName('regTask')[rememberThisTaskValue].style.background = 'rgba(255, 255, 255, 0.7)';
document.getElementsByClassName('regTask')[rememberThisTaskValue].onmouseover = function() {
this.style.background = 'rgb(255, 255, 255)';
}
document.getElementsByClassName('regTask')[rememberThisTaskValue].onmouseout = function() {
this.style.background = 'rgba(255, 255, 255, 0.7)';
}
}, 180)
// Switch by clicking second task.
}
}
}

我尝试过的:-使用不同的变量名-删除列表并立即重新放入页面。我想用这种方式重置计数器,让列表再次正常工作。-实现一个变量,该变量指示任务是否已被删除。如果该变量为正,则rememberThisTaskValue变量将减少1。

但这些都不起作用。

删除值后,事件侦听器和点击事件可能不再同步。最好将所有工作放在一个事件侦听器中,以防止出现差异。

我建议删除这篇文章:

var everyTask = document.querySelectorAll('.regTask');
for (var q = 0; q < everyTask.length; q++) {  
everyTask[q].addEventListener('click', ((h) => {          
return function() {
rememberThisTaskValue = h;
}
})(q))
}

然后只使用for循环的索引作为索引,而不是rememberThisTaskValue

document.getElementsByClassName('regTask')[b].remove();

因此,如果有人面临类似的问题,并以某种方式看到了这篇文章,下面是我如何想出一个主意的(尽管我不是100%,如果它成功了,时间会证明的(我会尽力解释为什么这个列表不能正常工作。因此,假设我们删除索引为[3]的任务。可能包括我在内的一些人希望列表现在是这样的:[0]、[1]、[2]、[4]。但任务[4]必须回到过去,占据空白。任务[5]必须取代[4]。这确实让我感到困惑,但这是我唯一剩下的想法。我仍然无法在脑海中想象,但我可能走在了正确的轨道上。。。

那我做了什么?

  • 我没有删除元素,而是这样设置:style.display = 'none'我没有删除它,只是让它不可见,所以spot[3]仍然不是空的,其他任务必须保留在它们的位置
  • 尽管如此,我还是想完全删除这些任务,以使我的列表中没有多余或已完成的任务。由于我添加了一个关闭此列表的选项——每次关闭它时,我都会选择具有该类名和display:none属性的所有任务并将其删除。当我下次打开列表时,这不应该影响它,因为所有计数器都应该重置

更新(2020年4月13日(:

因此,不幸的是,如果您想实现诸如移动任务之类的功能,上面的方法会产生一些不良后果。这也不是最好的选择。不过,我想与社区分享我的进步和知识,所以我很乐意向您展示我的新解决方案:

function editTasks() {
var everyTask = document.querySelectorAll('.regTask');
for (var q = 0; q < everyTask.length; q++) {  
everyTask[q].addEventListener('click', ((h) => {          
return function() {
rememberThisTaskValue = h;
}
})(q))
}
var allTasks = document.getElementsByClassName('regTask'); 
for (var b = 0; b < allTasks.length; b++) {
allTasks[b].onclick = function() {
document.getElementsByClassName('regTask')[rememberThisTaskValue].style.background = 'rgb(255, 255, 255)';
document.getElementsByClassName('regTask')[rememberThisTaskValue].onmouseover = function() {
this.style.background = 'rgb(255, 255, 255)';
}
document.getElementsByClassName('regTask')[rememberThisTaskValue].onmouseout = function() {
this.style.background = 'rgb(255, 255, 255)';
}
alert(rememberThisTaskValue);
temporaryLayer.style.animation = 'layerFadeIn 0.18s forwards';
temporaryLayer.style.background = 'rgba(0, 0, 0, 0.5)';
temporaryLayer.style.backdropFilter = 'blur(6px)';
body.appendChild(temporaryLayer);
var editor = document.createElement('div');
var editorTitle = document.createElement('h1');
var editorTitleNode = document.createTextNode('Edit task');
var editorSubTitle = document.createElement('h2');
// Styling
var editorSubTitleTextNodeContent = document.getElementsByClassName('regTask')[rememberThisTaskValue].innerHTML;
var editorSubTitleNode = document.createTextNode(editorSubTitleTextNodeContent);
var editorOptions = document.createElement('div');
var editorOptionsInput = document.createElement('input');
var editorOptionsDelete = document.createElement('button');
var editorOptionsDeleteNode = document.createTextNode('Delete');
var editorOptionsMove = document.createElement('button');
var editorOptionsMoveNode = document.createTextNode('Move');
var editorOptionsRename = document.createElement('button');
var editorOptionsRenameNode = document.createTextNode('Rename');
var editorOptionsCancel = document.createElement('button');
var editorOptionsCancelNode = document.createTextNode('Cancel');
// Styling
temporaryLayer.appendChild(editor);
editor.appendChild(editorTitle);
editorTitle.appendChild(editorTitleNode);
editor.appendChild(editorSubTitle);
editorSubTitle.appendChild(editorSubTitleNode);
editor.appendChild(editorOptions);
editorOptions.appendChild(editorOptionsRename);
editorOptionsRename.appendChild(editorOptionsRenameNode);
editorOptions.appendChild(editorOptionsMove);
editorOptionsMove.appendChild(editorOptionsMoveNode);
editorOptions.appendChild(editorOptionsDelete);
editorOptionsDelete.appendChild(editorOptionsDeleteNode);
editorOptions.appendChild(editorOptionsCancel);
editorOptionsCancel.appendChild(editorOptionsCancelNode);
editorOptionsCancel.onclick = function() {
// There is some styling here too but I am going to leave it just in case
editor.style.animation = 'editorFadeOut 0.18s forwards';
temporaryLayer.style.animation = 'layerFadeOut 0.18s forwards';
setTimeout (function() {
temporaryLayer.style.animation = 'none';
temporaryLayer.style.background = 'none';
temporaryLayer.style.backdropFilter = 'none';
editor.remove();
temporaryLayer.remove();
document.getElementsByClassName('regTask')[rememberThisTaskValue].style.background = 'rgba(255, 255, 255, 0.7)';
document.getElementsByClassName('regTask')[rememberThisTaskValue].onmouseover = function() {
this.style.background = 'rgb(255, 255, 255)';
}
document.getElementsByClassName('regTask')[rememberThisTaskValue].onmouseout = function() {
this.style.background = 'rgba(255, 255, 255, 0.7)';
}
}, 180)
}
editorOptionsDelete.onclick = function() {
document.getElementsByClassName('regTask')[rememberThisTaskValue].remove();
var nodes = listTaskViewer.childNodes;
for (var j = 0; j < nodes.length; j++) {
nodes[j].setAttribute('class', 'newSavedTask regTask');
nodes[j].style.animation = 'none';
nodes[j].style.opacity = '1';
}
localStorage.setItem("taskListSave", listTaskViewer.innerHTML);
listTaskViewer.innerHTML = 'none';
var theTasks = document.querySelectorAll('.regTask');
for (var s = 0; s < theTasks.length; s++) {  
theTasks[s].style.animation = 'none';
}
listTaskViewer.innerHTML = localStorage.getItem("taskListSave");
for (var y = 0; y < savedTasks.length; y++) {
savedTasks[y].onmouseover = function() {
this.style.background = 'rgba(255, 255, 255, 1)';
}
savedTasks[y].onmouseout = function() {
this.style.background = 'rgba(255, 255, 255, 0.7)';
}
editTasks();
}
var everyTask = document.querySelectorAll('.regTask');
for (var q = 0; q < everyTask.length; q++) {  
everyTask[q].addEventListener('click', ((h) => {          
return function() {
var rememberThisTaskValue = h;
}
})(q))
}
editor.style.animation = 'editorFadeOut 0.18s forwards';
temporaryLayer.style.animation = 'layerFadeOut 0.18s forwards';
stipText.style.animation = 'tipFadeIn 0.18s forwards';
setTimeout (function() {
temporaryLayer.style.animation = 'none';
temporaryLayer.style.background = 'none';
temporaryLayer.style.backdropFilter = 'none';
editor.remove();
temporaryLayer.remove();
}, 180)
}
...
}

所以。。。它是如何工作的?很重要的一点是,任务将再次被删除,而不仅仅是将其显示属性设置为无。正如您所看到的,现在整个代码块都在一个名为editTasks()的函数中,这在编写任务删除函数时非常重要。当一个任务被删除时,列表会被保存在我迄今为止用来保存任务的相同localStorage值下,并将保存的值再次附加到div中;列表基本上是重新加载的,有点像页面刷新。我已经知道这样的刷新可以解决这个问题,但我永远不知道如何在不让用户再次关闭和打开列表的情况下故意/工作地实现它,这样他们就可以删除一些任务。刷新完成后,会调用editTasks()函数,并为任务提供新的索引,这将有助于列表在单击时正确选择任务。剩下的代码只是一些样式和动画,以避免我的应用程序中出现混乱或奇怪的行为。这并不是什么重要的事情,因为并不是所有的列表都是这样工作的,它只是我列表中的一些设计功能。

相关内容

  • 没有找到相关文章

最新更新