在 dom 中呈现元素后事件侦听器不工作

Event listener not working after elements are rendered in the dom

我正在创建一个项目,当我单击某个类别卡片时,我会获取该类别的 ID 并重定向到电影屏幕。

我知道 index.js 中的 row.eventlistener() 将在渲染元素之前执行,这就是它不选择的原因身份证。在将每个新呈现的项目添加到容器之前,我应该如何将事件侦听器添加到每个新呈现的项目,以便我可以获得每个类别卡片的 ID。

index.js

async function getCategories() {
  let url = 'http://localhost:8080/movieCategories';
  try {
    let res = await fetch(url);
    return await res.json();
  } catch (error) {
    console.log(error);
  }
}


async function renderCategories() {
  let categories = await getCategories();
  let html = '';
  categories.forEach(category => {


    let htmlSegment = `
            <div class="category-card" id=${category.id}>
            <img src="./assets/images/sci-fi.jpg" alt="" class="card-img">
            <div class="name">${category.name}</div>
          </div>
        `;
    html += htmlSegment;
  });
  let container = document.querySelector('.category-grid');
  container.innerHTML = html;
}

 renderCategories();


document.querySelectorAll('div.category-card').forEach(row=>{
  row.addEventListener('click',event=>{
    console.log('Category clicked', event.currentTarget.id)
    window.location= 'movies.html?categoryId=' +event.currentTarget.id;
  });

});

index.html

<section class="category" >
  <h2 class="section-heading">Category</h2>
  <div class="category-grid">
  </div>
</section>

尝试:

async function getCategories() {
  let url = 'http://localhost:8080/movieCategories';
  try {
    let res = await fetch(url);
    return await res.json();
  } catch (error) {
    console.log(error);
  }
}


async function renderCategories() {
  let categories = await getCategories();
  let html = '';
  categories.forEach(category => {


    let htmlSegment = `
            <div class="category-card" id=${category.id}>
            <img src="./assets/images/sci-fi.jpg" alt="" class="card-img">
            <div class="name">${category.name}</div>
          </div>
        `;
    html += htmlSegment;
  });
  let container = document.querySelector('.category-grid');
  container.innerHTML = html;
}
 //es8
await renderCategories();

// fix timeout async render element
setTimeout(() => {
  document.querySelectorAll('div.category-card').forEach(row=>{
    row.addEventListener('click',event=>{
      console.log('Category clicked', event.currentTarget.id)
      window.location= 'movies.html?categoryId=' +event.currentTarget.id;
    });
  })
});

您不是在等待对 renderCategories 的调用,请将您的事件侦听器逻辑移动到 renderCategories 方法中,或者您可以使用立即调用的异步函数表达式或简称 IIAFE,更多信息请参见此处:

    (async () => {
        await renderCategories();
        document.querySelectorAll('div.category-card').forEach(row => {
           row.addEventListener('click', event => {
               console.log('Category clicked', event.currentTarget.id)
               window.location= 'movies.html?categoryId=' +event.currentTarget.id;
           });
        });
    })();

您也可以在创建事件时直接在 div 本身上添加事件并传递 id 或任何您想要的。

<div class="category-card" id=${category.id} onclick="onCatClick(${category.id})">

在此之后,您可以将您的逻辑移动到顶层 onCatClick 函数中。

function onCatClick(id) {
    console.log('Category clicked', id)
    window.location= 'movies.html?categoryId=' + id;
}

这是因为您的 styling/layout 不允许您使用锚元素。否则,您可以简单地将 div 替换为锚元素:

<a href="movies.html?categoryId=${id}"></a>