首页 > 解决方案 > 我的删除事件侦听器给了我一个错误

问题描述

我创建了一个虚拟的待办事项列表(请不要介意糟糕的设计/响应能力)。

效果很好,我可以添加项目,我可以通过选择删除,或者一次删除所有项目。问题出在最后一个,它有效,但它给了我一个错误:

未捕获的 DOMException:无法在“节点”上执行“removeChild”:要删除的节点不是该节点的子节点。在 HTMLButtonElement。(http://127.0.0.1:5500/scripts.js:46:26)

我观察到的一件事是,第一次删除所有元素时,它不会给我这个错误,但是如果我再试一次,它会给我那个错误。(即使动作本身有效)。

HTML/JS

const add = document.querySelector('.add-item');
const remove = document.querySelector('.remove-item');
const nameList = document.querySelector('.todo-list');
const textField = document.querySelector('.text');

//main event listener
add.addEventListener('click', function() {

        //conditions
        if (textField.value === '') {
            alert('The textfield is empty!');
            return;
        }

        //creating elements
        const newDiv = document.createElement('div');
        const newLi = document.createElement('li');
        const liContent = document.createTextNode(textField.value);
        const closeButton = document.createElement('div');
        const closeButtonContent = document.createTextNode('Delete item');


        //appending elements
        newLi.appendChild(liContent);
        newDiv.appendChild(newLi);
        newDiv.appendChild(closeButton);
        closeButton.appendChild(closeButtonContent);

        //adding classes
        newDiv.classList.add('todo-div');
        closeButton.classList.add('todo-close');

        //output
        nameList.appendChild(newDiv);
        textField.value = '';


        closeButton.addEventListener('click', function () {
            if (newDiv.className === 'todo-div') {
                nameList.removeChild(newDiv);
            }
        });

        remove.addEventListener('click', function() {
            if (newDiv.className === 'todo-div') {
                nameList.removeChild(newDiv);
            }
        })
});
body {
    background-color: #f4d9c6;
}

.text {
    position: absolute;
    top: 20%;
    left: 45%;
    transform: translate(-50%, -50%);
    width: 350px;
    height: 30px;
    outline: none;
    border: 1px solid #bea695
}

.add-item {
    position: absolute;
    top: 20%;
    left: 56%;
    transform: translate(-50%, -50%);
}

.remove-item {
    position: absolute;
    top: 20%;
    left: 60%;
    transform: translate(-50%, -50%);
}

.todo-div {
    background-color: grey;
    width: 250px;
    display: flex;
    justify-content: space-between;
    list-style-type: none;
}

.todo-close {
    background-color: red;
}
<!DOCTYPE html>
<html>
<head>
    <title>Page</title>
    <link rel="stylesheet" href="styles.css" type="text/css">
</head>
<body>
    <ul class="todo-list">
        <div class="container"></div>
        <input class="text" type="text">
        <button class="add-item">Add</button>
        <button class="remove-item">Remove </button>
    </ul>
    <script src="scripts.js"></script>
</body>
</body>
</html>

标签: javascript

解决方案


        remove.addEventListener('click', function() {
            if (newDiv.className === 'todo-div') {
                nameList.removeChild(newDiv);
            }
        })

每次添加 adiv时都会添加此事件处理程序,但是当单击删除按钮时,事件处理程序不会从按钮中删除。这意味着,稍后,所有这些事件处理程序仍然会触发,即使div它们的目标对象不再存在。

解决此问题的一种方法是对删除按钮使用单个事件处理程序,该按钮将删除所有相关div的 s(如果有)。您还需要将其移到“主要事件侦听器”之外。

    remove.addEventListener('click', function() {
        Array.from(nameList.children).forEach(element => {
            if (element.className === 'todo-div') {
                nameList.removeChild(element);
            }
        }
    })

    //main event listener
    add.addEventListener('click', function() {
    // ...

推荐阅读