Список дел в JavaScript - После удаления задачи вы не можете правильно выбрать другую. - PullRequest
1 голос
/ 11 марта 2020

Это мой первый большой проект, и я делаю список дел, и до сих пор все работало гладко, но я только заметил действительно неприятную проблему. Итак, я решил сделать опцию, чтобы отредактировать задачу, нажав на нее - вы получаете такие опции, как перемещение вверх и вниз, переименование и даже удаление. Я протестировал функцию удаления, и оказалось, что она работает не так, как задумано. Когда я хочу удалить задачу в первый раз, все работает хорошо. Это список дел. Давайте удалим задачу «d» После нажатия на задачу откроется это меню: Давайте нажмем «Удалить» И вуаля! Задача исчезла. Давайте удалим еще один. Как ... следующий, например. Давайте нажмем на задачу "f" Однако, как вы можете видеть ... вместо "f", выбрана задача "g". В заключение, после удаления одной задачи, повторная попытка удалить задачу приводит к невозможности выбрать нужную задачу должным образом. Вместо того, чтобы работать с выбранной задачей, вы работаете с задачей, которая следует за ней после. Почему это происходит? Любая помощь приветствуется! Заранее спасибо!

            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.

Хотя ни одна из них не работала.

Ответы [ 2 ]

2 голосов
/ 11 марта 2020

Возможно, прослушиватель событий и событие on click больше не синхронизируются при удалении значения. Лучше всего поместить всю работу в один приемник событий, чтобы избежать расхождений.

Я бы предложил удалить этот кусок:

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

Затем просто использовать индекс for-l oop для индекса вместо rememberThisTaskValue

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

0 голосов
/ 12 марта 2020

Итак, если кто-то столкнулся с подобной проблемой и каким-то образом смог увидеть эту статью, вот как я пришел к идее (хотя я не на 100%, если это сработало, время покажет) Я попытаюсь объяснить почему список не работал должным образом. Итак, допустим, мы удалим задачу с индексом [3]. Некоторые люди, возможно, в том числе и я, ожидают, что теперь список будет таким: [0], [1], [2], [4]. Но задание [4] должно go вернуться и занять пустое место. Задача [5] должна занять место [4]. Это честно меня смущает, но это единственная остающаяся идея, которая у меня есть. Я до сих пор не могу даже представить себе это в своей голове, но я, вероятно, на правильном пути ...

Так, что я сделал?

  • Вместо удаления элемента , Я установил это так: style.display = 'none' Я не удалил его, просто сделал его невидимым, поэтому spot [3] все еще не пуст и другие задачи должны оставаться на своих местах.
  • Тем не менее, Я хочу полностью удалить эти задачи, чтобы мой список фактически не содержал нежелательных или завершенных задач. Поскольку я добавил опцию закрытия этого списка - каждый раз, когда вы его закрываете, я выбираю все задачи с этим именем класса и свойством display:none и удаляю их. Это не должно повлиять на список, когда я открою его в следующий раз, поскольку все счетчики должны быть сброшены.

ОБНОВЛЕНИЕ (13.04.2020):

Итак К сожалению, описанный выше метод имеет некоторые плохие последствия, если вы хотите реализовать такие функции, как перемещение ваших задач. Это также просто не лучший вариант. Я хочу поделиться своим прогрессом и знаниями с сообществом, поэтому я с удовольствием покажу вам мое новое решение:

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)
            }
            ...
}

Итак ... как оно работает? Что ж, важно сказать, что задачи снова удаляются, вместо того, чтобы просто установить для их свойства display значение none. Как видите, весь кусок кода теперь находится внутри функции, которая называется editTasks(), что очень важно при написании функции удаления задачи. Когда задача удаляется, список сохраняется под тем же значением localStorage, которое я использовал до сих пор, чтобы сохранить задачи и снова добавить сохраненное значение в div; список в основном перезагружен, что-то вроде страницы refre sh. Я уже знал, что такое refre sh устраняет проблему, но я никогда не знал, как реализовать это специально, без необходимости закрывать пользователя и снова открывать список, чтобы они могли удалить несколько задач. Когда это refre sh будет выполнено, вызывается функция editTasks(), которая дает задачам новые индексы, что поможет списку правильно выбирать задачи при нажатии. Оставшийся код - это просто стилизация и работа с анимацией, чтобы избежать путаницы или странного поведения в моем приложении. На самом деле это не что-то важное, так как не все списки работают так, это просто некоторые особенности дизайна, которые присутствуют в моем списке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...