【问题标题】:How to remove array item on click event? Vanilla JS如何在单击事件中删除数组项?香草JS
【发布时间】:2020-09-26 20:04:17
【问题描述】:

我正在使用 vanilla JS,我可以推送到数组,并从数组中删除最后一项。接下来我试图在点击时删除数组项。我在下面创建的功能有效,但它不正确?我哪里错了?我不想从 DOM 中删除该项目,我宁愿从数组中删除该项目,然后更新 UI 状态。

下面的代码:

let someData = [
    'This is some serious data part 2',
    'This is some serious data part 3', 
    'This is some serious data part 4', 
]; 

const loopIt = (data) => {
    let item = '';
    for (let i = 0; i < data.length; i++) {
        item += `<li>${data[i]}<button class='testBtn'>Remove ${i}</button></li>`;
    }
    return item;
}

let getHtml = () => {
    domElem.selector.innerHTML = loopIt(someData);
}

const clickEvents = () => {
    domElem.button.addEventListener ('click', function () {
        let inputData = domElem.input.value;
        if (inputData.length > 0) {
            someData.push(inputData);
        } else {
            alert('no input');
        }
        getHtml();
    });
    domElem.buttonRemove.addEventListener ('click', function () {
        someData.pop();
        getHtml();   
    });
}


const removeArrayItem = () => {
    let queryS = document.querySelectorAll('.testBtn');
        for (let i = 0; i < queryS.length; i++) {
            let index = queryS[i];
            index.addEventListener('click', function () {
                alert(i);
                someData.splice(i, 1);
                console.log(someData);
                getHtml();
            });
        };
}

const init = () => {
    getHtml();
    elemAttributes();
    clickEvents();
    removeArrayItem();
}

let initialise = init();

我的removeArrayItem

  • 1 - 查询 dom (let queryS = document.querySelectorAll('.testBtn');)
  • 2 - 遍历数组, 返回索引值 (i) (Loop function)
  • 3 - 添加事件 监听数组中的每个元素
  • 4 - 删除数组项 (拼接方法)-
  • 5 - 更新 UI(getHtml() 函数);

但是有什么地方出了问题?因为第一次点击后 UI 不会更新。

如果我推送项目,我无法在点击时删除它们。

【问题讨论】:

  • HTML 是如何连接到 someData 数组的?你能发布一个工作示例吗?

标签: javascript arrays


【解决方案1】:

这与您正在重置按钮所在的innerHTML 有关。这意味着与事件侦听器的所有绑定都已消失。因此,您必须在每次重新呈现 HTML 时重置事件侦听器或使用 事件委托

事件委托有一个事件侦听器,用于侦听冒泡的事件。例如:您单击按钮,单击事件会在 DOM 中冒泡并到达您侦听事件的元素。从那里您可以确定单击了哪个元素以及接下来要做什么。这种方法的优点是,您正在收听的该元素中的子元素可以是动态的,因此可以添加、移动、删除和更改,而无需考虑它。

在您的loopIt 函数中,将i 索引传递给按钮中的属性。您不再需要监听按钮本身的点击,因此它需要保存一些数据供事件监听器处理。 value 属性非常适合此目的。

const loopIt = (data) => {
    let item = '';
    for (let i = 0; i < data.length; i++) {       // Right here ↓
        item += `<li>${data[i]}<button class="testBtn" value="${i}">Remove ${i}</button></li>`;
    }
    return item;
}

按钮现在知道每次单击按钮时需要拼接的数组索引的索引。

修改removeArrayItem函数。与其监听每个按钮的点击,不如监听父元素上的点击事件,我认为是domElem.selector?

const removeArrayItem = () => {
    domElem.selector.addEventListener('click', function(event) {
        const clickedElem = event.target; // This is the element that fired the click.
        if (clickedElem.classList.contains('testBtn')) {
            const index = clickedElem.value // The index in the array.
            someData.splice(index, 1); // Splice array.
            getHtml(); // Re-render the HTML.
        }
    });
}

这会添加一个事件侦听器并获取targetEvent 对象,这是触发点击事件的元素。然后它检查它是否有一个包含testBtn 类的类。如果是,它会从value 属性中获取i 索引,拼接数组并重新渲染HTML。

试试看。您的点击应该每次都有效。

【讨论】:

  • 谢谢你,这解释得很好,给了我更多研究的基础
【解决方案2】:

我将通过查找元素并删除数组中的元素来应对这一挑战,删除后我将清空 innerHTML 并根据新数组重建 UI,就像您描述的那样。

我的代码解决方案如下所示:

在这里,我通过 onClick 属性分配每个项目。我创建了一个名为 removeItem 的方法,并传递了一个响应数组中元素的参数。

方法 removeItem 然后可以删除给定的元素,然后及时重建 UI。

let someData = [
    'This is some serious data part 2',
    'This is some serious data part 3',
    'This is some serious data part 4'
];

const loopIt = (data) => {
    let item = '';
    for (let i = 0; i < data.length; i++) {
        item += `<li>${data[i]}<button onClick='removeItem(${i})'class='testBtn'>Remove ${i}</button></li>`;
    }
    return item;
};

let removeItem = (index) => {
    someData.splice(index, 1);
    getHtml();
};
let getHtml = () => {
    domElem.innerHTML = '';
    domElem.innerHTML = loopIt(someData);
};

const init = () => {
    getHtml();
};

let initialise = init();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-18
    • 2021-09-30
    • 2016-12-11
    • 1970-01-01
    • 1970-01-01
    • 2019-01-18
    相关资源
    最近更新 更多