javascript - forEach 代码不起作用,但两个不同的 forEach 函数中的相同代码却起作用,为什么?

标签 javascript arrays foreach onclick

我有一个名为“filteredTasks”的数组,对于每个任务,我想在 Div 中创建一个按钮并向该按钮添加一个 onclick 函数。我创建了一些代码(您可以在下面的第一个 block 中看到)来执行此操作。这不起作用,按钮已正确创建,但 onclick 函数仅添加到最后一个按钮。 当我使用完全相同的代码,但分成 2 个不同的 forEach 回调(您也可以在下面的第二部分中查看)时,它确实有效。 简而言之,当尝试创建按钮并在创建时向每个按钮添加 onclick 函数时,只有最后一个按钮正确接收 onclick 函数。但是当我首先创建所有按钮,然后为每个按钮添加 onclick 函数时,它确实有效。我不明白这是为什么。这里有更好的开发人员可以向我指出原因吗? 非常感谢!

        filteredTasks.forEach(function(task) {
            var buttonId = task.taskName.replace(/\s/g, '') + 'Button'
            var taskHTML = `<button class="taskButton" id="${buttonId}">${task.taskName}</button>`;
            taskDiv.innerHTML += taskHTML;
            var button = document.querySelector(`#${buttonId}`);
            button.onclick = function() {performTask(task)};
        });
    };





        filteredTasks.forEach(function(task) {
            var buttonId = task.taskName.replace(/\s/g, '') + 'Button'
            var taskHTML = `<button class="taskButton" id="${buttonId}">${task.taskName}</button>`;
            taskDiv.innerHTML += taskHTML;
        });

        filteredTasks.forEach(function(task) {
            var buttonId = task.taskName.replace(/\s/g, '') + 'Button'
            var button = document.querySelector(`#${buttonId}`);
            button.onclick = function() {performTask(task)};
        });
    };

最佳答案

我怀疑这与您处理 DOM 更新的方式有关。您的代码仅将事件添加到最后一个按钮。这是a known issue with for/loops )。使用 forEach 代替 for/loop would normally fix this ,但显然不是在这种情况下。 (我知道这有点麻烦。另一个 SO 成员可能有更详细的技术原因来解释为什么它在这种情况下不起作用。)

也就是说,正如您所发现的,分阶段执行此操作会更好,但您应该更进一步。它将避免陷入您现在所处的情况,并且性能会更高。

目前,您正尝试在一个循环中完成所有操作:创建任务 html、将其添加到 DOM 以及将事件监听器添加到新按钮。您应该做的是创建所有 HTML,然后将那个添加到DOM,然后使用它们的类一次选取所有按钮并向它们添加监听器。

const filteredTasks = [{ taskName: 'bob' },{ taskName: 'dave' }];
const tasks = document.querySelector('#tasks');

// Use `map` to create all the buttons
// I've used a data attribute here instead of an actual id
const html = filteredTasks.map(task => {
  const buttonId = `${task.taskName.replace(/\s/g, '')}Button`;
  return `<button class="taskButton" data-id="${buttonId}">${task.taskName}</button>`;
}).join('');

// Add that HTML to the DOM with one update
tasks.innerHTML = html;

// Grab all the taskButton buttons using their class,
// and add click listeners to them
const buttons = document.querySelectorAll('.taskButton');
[...buttons].forEach(button => button.addEventListener('click', performTask, false));

// `performTask` destructs the event target (clicked button)
// and logs the id 
function performTask(e) {
  const { dataset: { id } } = e.target;
  console.log(id);
}
<div id="tasks"></div>

关于javascript - forEach 代码不起作用,但两个不同的 forEach 函数中的相同代码却起作用,为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54217881/

相关文章:

javascript - 如何告诉 ionic 幻灯片显示什么幻灯片 (slideTo)

javascript - Knockout js 在子对象中显示过滤列表。访问父对象列表以进行过滤

javascript - 在模糊事件中添加异常(exception)

python - 制作统计程序

javascript - 清除输入事件 - HTML 和 JavaScript

arrays - 求 Swift 数组中元素的总和

arrays - bash:缺少数组的第一个元素

php - 在每个 foreach 循环迭代中包含 Blade 模板重复

.net - 将项目添加到字典的 LINQ 方法

javascript - angularjs foreach循环通过依赖于先前请求的http请求