【问题标题】:remove function deletes wrong items from arrayremove 函数从数组中删除错误的项目
【发布时间】:2020-08-29 19:26:13
【问题描述】:

所以我正在制作我的待办事项应用程序,我遇到了这个奇怪的问题,我的 removeToDo 函数以奇怪的模式定位错误的项目,除了第一个删除的项目(它总是被很好地删除)。假设我们在数组中有 id 从 0 到 6 的项目:

Clicked to remove item with ID = 3 - removed item with ID = 3
Clicked to remove item with ID = 4 - removed item with ID = 5
Clicked to remove item with ID = 5 - removed item with ID = 6
Clicked to remove item with ID = 0 - removed item with ID = 0
Clicked to remove item with ID = 2 - removed item with ID = 4
Clicked to remove item with ID = 1 - removed item with ID = 2
Clicked to remove item with ID = 6 - removed item with ID = 1

所以它并没有真正遵循一个明显的模式(认为它可能是 id + 1 之类的东西,但看起来不像)。另外我第二次做了和上面完全相同的测试,看看它是否随机化,它没有,结果完全一样。

这是一些代码 HTML

<body>
    <div class='app'>

        <ul id='list'>

        </ul>
        <div class="footer">
            <i class="fas fa-plus-circle" aria-hidden="true" id='addButton'></i>
            <input type="text" id='itemInput' placeholder="Add a to-do" />
        </div>
    </div>
<script src="./app.js"></script>

</body>

JS

const list = document.getElementById("list");
const input = document.getElementById("itemInput");

let id;

//get the item from the local storage
let data = localStorage.getItem('TODO');

//check if data is not empty
if(data) {
    LIST = JSON.parse(data)
    id = LIST.length; // set the list id to the last in the array
    loadList(LIST); // load all the items in the array to the UI 
} else {
    //if data is empty
    LIST = [];
    id = 0;
}

function loadList(array) {
    array.forEach(item => {
        addToDo(item.name, item.id, item.done, item.trash);
    })
}

function addToDo(toDo, id, done, trash) {

    // if trash is true do not execute the code below
    if (trash) {return ;}
    const DONE = done ? check : uncheck;
    const LINE = done ? lineThrough : "";

    const text =`
    <li class="item">
        <i class="far ${DONE}" id='${id}'></i>
            <div class="description ${LINE} wrap">${toDo}</div>
        <i class="fas fa-trash-alt" id='${id}'></i>
    </li>`;
    const position = "beforeend";
    list.insertAdjacentHTML(position, text);        
}

// remove to-do
function removeToDo(element, i) {
    let newList = [...LIST]
    element.parentNode.parentNode.removeChild(element.parentNode);
    i = newList.indexOf(newList[event.target.id]) //<-- i think that is the problem, the indexing is not working as it should, as a result app gets confused ?
    alert(i)
    //newList[event.target.id].trash = true;  
    newList.splice(i, 1);
    LIST = newList;
    console.log(LIST);
    return LIST;

}

// click listener for job complete and job delete
list.addEventListener('click', e => {
    const element = e.target;
    if(e.target.className == "fas fa-trash-alt" ){
        removeToDo(element);
    }else if(e.target.className == "far fa-circle") {
        jobComplete(element);
    }else if(e.target.className == "far fa-check-circle"){
        jobComplete(element);
    }
    }
)

//add a task with "enter" key
document.addEventListener("keyup", (event) => {
    if(event.keyCode == 13){
        const toDo = input.value;
            if(toDo) {
                addToDo(toDo, id, false, false);
                LIST.push(
                    {
                        name: toDo,
                        id: id,
                        done: false,
                        trash: false
                    }
                );
                localStorage.setItem('TODO', JSON.stringify(LIST));
                id++;
                input.value = '';
            }
        }
})

编辑: 以奇怪的模式删除的项目在 LIST 数组中,我单击的实际按钮被删除得很好。我觉得我解释得不够清楚

【问题讨论】:

  • 不要使用element.parentNode.parentNode.removeChild(element.parentNode);,而是使用element.remove(),当你有正确的元素应该被取出时。
  • 它只是删除了 bin 图标,这就是它存在的原因。 element.parentNode.remove(); 可以删除它,但原来的问题仍然存在。
  • 请展示您将获得的localStorage 字符串示例。
  • @ScottMarcus Storage TODO: "[{"name":"1","id":0,"done":false,"trash":false}, {"name":"2 ","id":1,"done":false,"trash":false}, {"name":"3","id":2,"done":false,"trash":false}, { "name":"4","id":3,"done":false,"trash":false}, {"name":"5","id":4,"done":false,"trash ":false}, {"name":"6","id":5,"done":false,"trash":false}, {"name":"7","id":6,"done ":false,"trash":false}, {"name":"8","id":7,"done":false,"trash":false}]" 长度:1__proto__:存储

标签: javascript html css arrays indexing


【解决方案1】:

我认为最好不要考虑删除项目的 id。 您也可以考虑价值。 代替 splice(i,1),请尝试使用

newList = newList.filter(function( obj ) {
  return obj.name !== element.previousElementSibling.innerHTML;
});

【讨论】:

  • 好的,到目前为止这似乎是有效的,但是你能向我解释一下这个方法吗?我想了解它在那里做了什么并实际学到了一些东西:) 还有一个问题,ID 仍然是一个问题,因为每当我删除某些东西时,console.log 会显示正确的 ID,只有少数第一次删除,然后它就消失了一切都为-1?此外,如果我删除某些内容然后添加新的待办事项,它的 id 为 -1 ?
  • 感谢您接受我的回答。因此,在拼接一次数组后,它的 id 与 DOM 中的元素不同(检查元素并检查)。函数中传递的 id 是元素的 id,但数组索引拼接项目后元素发生了变化。所以我采用了 bin 图标的前一个兄弟的 html,即图标上方的 div 并使用了数组过滤方法(将文本与 obj 的 name 属性进行比较,这在你的case) 过滤掉除删除的元素之外的其余元素并将其分配给原始数组
【解决方案2】:

问题是这样的:

 id = LIST.length; // set the list id to the last in the array

数组的.length 属性返回数组中的项目数,但数组索引从零开始。一个包含 5 个项目的数组 (length === 5),其最后一个项目的索引将是 4

数组中最后一项的索引是.length -1

【讨论】:

  • 我试过了,可惜没有解决问题:(
  • @PawelKrzesinski 这仍然是一个问题,应该得到纠正。
猜你喜欢
  • 2019-06-28
  • 2019-10-05
  • 1970-01-01
  • 2022-01-13
  • 2011-07-06
  • 1970-01-01
  • 2021-10-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多