将事件侦听器添加到容器中具有相同 class 的多个 div

add event listener to multiple divs with same class in a container

我有一个 16x16 的网格,我想为此网格中的每个 div 添加一个事件侦听器。首先,我使用 document.querySelectorAll() 选择了容器中的所有 div。然后我使用 forEach() 遍历这个列表。这没有用,所以我尝试了 container.childNodes.forEach(),但仍然面临同样的问题。非常感谢任何帮助。

这是我的代码:

const container = document.querySelector(".container");
const gridItem = document.querySelectorAll(".grid-item").forEach(gridItem => gridItem.addEventListener("click", myFunc));



function makeGrid(rows,cols) {
    container.style.setProperty("--grid-rows",rows);
    container.style.setProperty("--grid-cols",cols);

    for (let i = 0; i < (rows*cols); i++) {
        let gridItem = document.createElement("div");
        container.appendChild(gridItem).classList.add("grid-item");
    }
}

makeGrid(16,16);


function myFunc() {
    console.log("hello");
}

你只是把事情搞砸了。首先创建您的网格,然后应用事件侦听器。实际上,它正在循环尝试应用侦听器的空数组。

const container = document.querySelector(".container");
function makeGrid(rows, cols) {
  container.style.setProperty("--grid-rows", rows);
  container.style.setProperty("--grid-cols", cols);

  for (let i = 0; i < (rows * cols); i++) {
    let gridItem = document.createElement("div");
    gridItem.innerHTML = "grid item";
    container.appendChild(gridItem).classList.add("grid-item");
  }
}

makeGrid(16, 16);
document.querySelectorAll(".grid-item").forEach(gridItem => gridItem.addEventListener("click", myFunc));

function myFunc() {
  console.log("hello");
}
<div class='container'>

</div>

看你的逻辑。

  1. Select一个元素
  2. 找到所有的 .grid-item 元素
  3. 定义一个创建网格项的函数
  4. 调用创建网格项的函数

所以按照这个逻辑,你显然不会找到任何元素。您需要在 select 之前创建网格项目元素。您也没有正确地将 class 添加到元素中

因此更改顺序:

function myFunc() {
  console.log("hello", this);
}

const container = document.querySelector(".container");
makeGrid(16, 16);
const gridItem = document.querySelectorAll(".grid-item").forEach(gridItem => gridItem.addEventListener("click", myFunc));


function makeGrid(rows, cols) {
  container.style.setProperty("--grid-rows", rows);
  container.style.setProperty("--grid-cols", cols);

  for (let i = 0; i < (rows * cols); i++) {
    const gridItem = document.createElement("div");
    gridItem.classList.add("grid-item");
    gridItem.textContent = i + 1;
    container.appendChild(gridItem)
  }
}
.container {
  --grid-cols: 2;
  display: grid;
  grid-template-columns: repeat(var(--grid-cols), 1fr);
  gap: .1em;
}

.grid-item {
  border: 1px solid #CCC;
  padding: .2em;
  text-align: center;
}
<div class="container"></div>

但为什么不在创建元素时绑定事件?

function myFunc() {
  console.log("hello", this);
}

const container = document.querySelector(".container");

function makeGrid(rows, cols) {
  container.style.setProperty("--grid-rows", rows);
  container.style.setProperty("--grid-cols", cols);

  for (let i = 0; i < (rows * cols); i++) {
    const gridItem = document.createElement("div");
    gridItem.classList.add("grid-item");
    gridItem.addEventListener("click", myFunc);
    gridItem.textContent = i + 1;
    container.appendChild(gridItem)
  }
}

makeGrid(16, 16);
.container {
  --grid-cols: 2;
  display: grid;
  grid-template-columns: repeat(var(--grid-cols), 1fr);
  gap: .1em;
}

.grid-item {
  border: 1px solid #CCC;
  padding: .2em;
  text-align: center;
}
<div class="container"></div>

或者只使用事件委托

function myFunc(event) {
  console.log("hello", event.target.closest('.grid-item'));
}

const container = document.querySelector(".container");
container.addEventListener("click", myFunc);


function makeGrid(rows, cols) {
  container.style.setProperty("--grid-rows", rows);
  container.style.setProperty("--grid-cols", cols);

  for (let i = 0; i < (rows * cols); i++) {
    const gridItem = document.createElement("div");
    gridItem.classList.add("grid-item");
    gridItem.textContent = i + 1;
    container.appendChild(gridItem)
  }
}

makeGrid(16, 16);
.container {
  --grid-cols: 2;
  display: grid;
  grid-template-columns: repeat(var(--grid-cols), 1fr);
  gap: .1em;
}

.grid-item {
  border: 1px solid #CCC;
  padding: .2em;
  text-align: center;
}
<div class="container"></div>

您不需要为每个元素创建一个侦听器。您可以只在父元素上创建一个侦听器,并有条件地在函数中调用您的代码:

const container = document.querySelector(".container");
// add a single listener to the parent element of the grid items
container.addEventListener("click", myFunc);

// -- snip --

function myFunc(event) {
    // only run the code if the clicked element matches the selector
    if (event.target.matches(".grid-item")) {
        console.log("hello");
    }
}

另请参阅:Element.matches() - Web APIs | MDN