使用事件侦听器时如何访问父容器上的属性?

时间:2019-10-29 07:29:09

标签: javascript addeventlistener

我已将事件侦听器附加到容器元素。我已经向容器元素添加了data属性,并且在单击容器时正在调出data属性,因此效果很好。我可以看到,当我单击容器内的任何子级时,它还会触发事件侦听器,但随后无法获取数据属性。有什么想法可以在单击孩子时获得容器的data属性吗?

在此处查看实际操作:https://js-addeventlistener-demo.stackblitz.io

HTML:

<div class="group">
  <div class="container" data-letter="A">
    <h2>A</h2>
    <span>Subtitle</span>
  </div>

  <div class="container" data-letter="B">
    <h2>B</h2>
    <span>Subtitle</span>
  </div>

  <div class="container" data-letter="C">
    <h2>C</h2>
    <span>Subtitle</span>
  </div>
</div>

JavaScript:

const containers = document.querySelectorAll('div.container');

containers.forEach(container => {
  container.addEventListener('click', e => {
    console.dir(e.target);
    console.log('The dataset letter for the container element is', e.target.dataset.letter);
  });
});

4 个答案:

答案 0 :(得分:2)

由于事件bubbling,您将获得容器中的所有点击以及子元素带来的所有事件。

target事件属性是指触发事件的元素,而不是容器本身(期望直接单击容器)。

您应该使用currentTarget事件属性,该属性引用附加了侦听器的元素。

containers.forEach(container => {
  container.addEventListener('click', e => { 
    console.log(
      'The dataset letter for the container element is', 
      e.currentTarget.dataset.letter
    );
  });
});

答案 1 :(得分:1)

您可以像这样检查状况

如果未定义e.target.dataset.letter,则可以检查父元素。

containers.forEach(container => {
  container.addEventListener('click', e => {
    console.dir(e.target);
    console.log('The dataset letter for the container element is', (e.target.dataset.letter!=undefined) ? ""+e.target.dataset.letter : ""+e.target.parentElement.dataset.letter);
  });
});

答案 2 :(得分:1)

您可以从container访问foreach argument

const containers = document.querySelectorAll('div.container');

containers.forEach(container => {
  container.addEventListener('click', e => {
    console.dir(e.target);
    console.log('The dataset letter for the container element is', container.dataset.letter);
  });
});
<div class="group">
  <div class="container" data-letter="A">
    <h2>A</h2>
    <span>Subtitle</span>
  </div>

  <div class="container" data-letter="B">
    <h2>B</h2>
    <span>Subtitle</span>
  </div>

  <div class="container" data-letter="C">
    <h2>C</h2>
    <span>Subtitle</span>
  </div>
</div>

答案 3 :(得分:0)

您可以获取目标并使用container检查目标是否具有类classList.contains。如果不是,则使用closest获得与容器类最接近的div。例如,如果您单击容器(绿色边框),classList.contains将返回true,因为它具有类。但是,单击没有类容器的h2或span将使用最近的

获得最接近的container

const containers = document.querySelectorAll('div.container');

containers.forEach(container => {
  container.addEventListener('click', e => {
    if (e.target.classList.contains('container')) {
      console.log(e.target.dataset.letter);
    } else {
      let getClosestContainer = e.target.closest('.container');
      console.log(getClosestContainer.dataset.letter)

    }

  });
});
.container {
  border: 1px solid green;
}

h2 {
  border: 1px solid red;
}

span {
  border: 1px solid yellow;
}
<div class="group">
  <div class="container" data-letter="A">
    <h2>A</h2>
    <span>Subtitle</span>
  </div>

  <div class="container" data-letter="B">
    <h2>B</h2>
    <span>Subtitle</span>
  </div>

  <div class="container" data-letter="C">
    <h2>C</h2>
    <span>Subtitle</span>
  </div>
</div>