如何捕捉中间的事件

时间:2017-04-24 07:46:23

标签: javascript

我想附加一个click事件监听器,并在此上下文中使用“data-attr”运行一些操作,尽可能优雅。

<div id="container">

    <div class="group" data-attr="info1">
        <div class="a-casual-class-1">***</div>
        <div class="a-casual-class-2">AAA</div>
    </div>

    <div class="group" data-attr="info2">
        <div class="a-casual-class-1">***</div>
        <div class="a-casual-class-2">AAA</div>
    </div>

</div>

A)只有一个事件发生在根(#container)

  • 检查event.target是a-casual-class-1还是a-casual-class-2并获取父元素以检索数据属性或
  • 从root和data-attr中检索.group元素。

B)我可以首先得到'.group'的节点列表,创建一个循环并将事件监听器附加到每个元素。

有没有更好的方法来处理这种情况?

2 个答案:

答案 0 :(得分:2)

  

A)只有一个事件发生在根(#container)

您可以使用document.querySelectorAll()定位所有内部div。

  

B)我可以先获得&#39; .group&#39;的节点列表,制作一个循环并附加该元素。

当你创建一个选择器时,它会给你一个像dom节点对象的数组。你必须遍历它们并绑定事件。

所以总的想法是,由于事件在DOM中起泡,你可以在#container的子div上绑定事件。现在每当你点击.group的子div时,它总会找到得到事件绑定的div并且只执行回调。

&#13;
&#13;
var divs = document.querySelectorAll('#container > div');

// divs.forEach(function(div){ // it worked at chrome 57
[].forEach.call(divs, function(div){ // changed if user is on old version of browser
  div.addEventListener('click', function(e){
    var data = this.dataset.attr;
    console.log(data);
  });
});
&#13;
<div id="container">
  <div class="group" data-attr="info1">
    <div class="a-casual-class-1">***</div>
    <div class="a-casual-class-2">AAA</div>
  </div>

  <div class="group" data-attr="info2">
    <div class="a-casual-class-1">***</div>
    <div class="a-casual-class-2">AAA</div>
  </div>
</div>
&#13;
&#13;
&#13;

答案 1 :(得分:1)

  

A)只有一个事件发生在根(#container)

如果结构不是太复杂,那么您可以将事件绑定到根并检查event.target类以运行您的操作。

  

检查event.target是a-casual-class-1还是a-casual-class-2并获取   父元素检索数据属性或检索.group   来自root和data-attr的元素。

您可以检查父级,然后执行操作,而不是检查a-casual-class-1

例如:

var target = document.getElementById('container');
target.addEventListener('click', doAction);

function doAction(e) { 
  if (e.target.className === 'group') {
    console.log(e.target.dataset.attr);
  }
  if (e.target.parentElement.className === 'group') {
    console.log(e.target.parentElement.dataset.attr);
  }	
}
#container {
  margin: 12p; padding: 12px;
  border: 4px solid #b33;
}
.group {
  margin: 12px; padding: 12px;
  border: 4px solid #33b; 
}
.group > div { background-color: #ddd; }
<div id="container">
  <div class="group" data-attr="info1">
    <div class="a-casual-class-1">***</div>
    <div class="a-casual-class-2">AAA</div>
  </div>
  <div class="group" data-attr="info2">
    <div class="a-casual-class-1">***</div>
    <div class="a-casual-class-2">AAA</div>
  </div>
</div>

  

B)我可以先获得'.group'的节点列表,然后进行循环   将事件监听器附加到每个元素。

如果您的标记和结构变得复杂,那么最好使用.groups遍历querySelectorAll,然后将事件绑定到其中的每一个。这是另一个答案中显示的内容。

底线:看看你的代码是否开始变得过于复杂,具体取决于标记结构的复杂程度。此外,您需要考虑是否有其他事件处理程序绑定到嵌套在#container中的兄弟和/或子项。在这种情况下,您可能会发现自己正在摆弄capture和/或stopPropagation