0

我的应用程序中有一个卡片 div。当用户点击这个卡片元素时,它应该触发一个模式。但是,我似乎无法为卡片元素内的所有元素附加事件监听器。

卡片元素如下所示:

<div class="card" data-id=${index}>
      <div class="card-img-container">
          <img class="card-img" src="${thumbnail}" alt="profile picture">
      </div>
      <div class="card-info-container">
          <h3 id="name" class="card-name cap">${firstname} ${lastname}</h3>
          <p class="card-text">${email}</p>
          <p class="card-text cap">${city}, ${state}</p>
      </div>
  </div>

如何创建一个监听卡片元素内所有元素的事件监听器?这是我的事件监听器的样子:

document.querySelector('.card').addEventListener('click', (e) => {
let dataId = parseInt(e.target.dataset.id);
let user = users[dataId];
showModal(user);

document.getElementById('modal-close-btn').addEventListener('click', () => {
  const modal = document.querySelector('.modal-container');
  document.body.removeChild(modal);
});

});

4

3 回答 3

0

我认为您已经走上了正轨-尽管您的问题不是很清楚。您不需要将每个元素绑定到侦听器,只需捕获父级(在本例中为“.card”)并确定单击了哪个元素,就像您所做的那样。

document.querySelector(".card").addEventlistener("click", function(el){ el.target; //was clicked });

如果你真的想绑定卡片中的所有子元素(不推荐),那么 document.querySelector(".card *").addEventListener("click", function(){ });

如果这不是您所需要的,那么也许我不明白这个问题

于 2020-07-09T18:27:12.150 回答
0

如果您需要将事件侦听器设置为具有相同类的多个元素,您可以使用for循环来循环每个元素。附上您的代码,其中包含一个 for 循环。

//Create a for loop and loop through all elements that coorespond with (document.querySelectorAll('.card'))

    //Sidenote: querySelectorAll() returns an array of all matching elements, so you can simply add an event listsner to each element in that array by it's index or by adding "[i]" 
    for(let i =0; i < document.querySelectorAll('.card').length; i++){

        document.querySelectorAll('.card')[i].addEventListener('click', (e) => {
        let dataId = parseInt(e.target.dataset.id);
        let user = users[dataId];
        showModal(user);

            document.getElementById('modal-close-btn').addEventListener('click', () => {
              const modal = document.querySelector('.modal-container');
              document.body.removeChild(modal);
            });
        });
    }


    //This should attach your "click" event listener to any elements with the class of "card"

这会将事件侦听器设置为所有“卡片”,但您可以对任何元素应用相同的方法/for 循环。希望这可以帮助

于 2020-07-09T18:42:10.067 回答
0

没有理由为卡片中的每个元素添加事件侦听器。而是将事件侦听器绑定到.card元素。然后用于event.currentTarget获取您的元素。

请记住,target是您单击的元素,并且currentTarget是冒泡过程中的当前元素(事件绑定到的元素)。

在您的示例e.target.dataset.id中,很可能会返回undefined,因为您单击了.carddiv 内的元素。parseInt(undefined)将返回NaN并且users[NaN]很可能还会返回undefined。这意味着大部分时间你都会打电话showModal(undefined),除非你点击卡片填充(如果有的话)。

使用currentTarget应该可以解决问题。

document.querySelector(".card").addEventListener("click", event => {
  console.log("target:", event.target);
  console.log("currentTarget:", event.currentTarget);
  // this is how you get your ".card" element ^
});
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">

<div class="card" data-id=${index}>
    <div class="card-img-container">
        <img class="card-img" src="${thumbnail}" alt="profile picture">
    </div>
    <div class="card-info-container">
        <h3 id="name" class="card-name cap">${firstname} ${lastname}</h3>
        <p class="card-text">${email}</p>
        <p class="card-text cap">${city}, ${state}</p>
    </div>
</div>

于 2020-07-09T18:50:48.620 回答