JavaScript事件和冒泡

Lor*_*con 5 javascript javascript-events event-bubbling

我有以下(简化)标记代码:

<div id="container">
    <div data-value="1">
        <span>Click me 1</span>
    </div>
    <div data-value="2">
        <span>Click me 2</span>
    </div>
</div>
<div id="messages"></div>
Run Code Online (Sandbox Code Playgroud)

我想通过仅在其上附加事件监听器来利用冒泡#container,并获取被点击的子项data-value.

document.getElementById('container').addEventListener('click', function(e){
    document.getElementById('messages').innerHTML = 'you clicked ' + e.target.dataset.value;
}, false);
Run Code Online (Sandbox Code Playgroud)

如果点击的区域是div区域(小提琴中的红色),一切正常.我怎样才能获得data-value也只有当点击来自DIV的儿童(如点击蓝色跨度)的数据值,而不改变事件监听器?

这是小提琴:http://jsfiddle.net/hgLagy31/1/

Dan*_*mms 4

e.target是用户单击的元素,它之所以显示是undefined因为它<span>没有属性data-value。您可以沿着树向上查找包含data-value.

document.getElementById('container').addEventListener('click', function(e) {
  // Find nearest ancestor with data-value defined
  var node = e.target;
  while (!node.dataset.value) {
    node = node.parentNode;
  }
  document.getElementById('messages').innerHTML =
    'you clicked ' + node.dataset.value;
}, false);
Run Code Online (Sandbox Code Playgroud)
#container > div {
  background: red;
}
#container > div > span {
  background: blue;
  color: white;
}
Run Code Online (Sandbox Code Playgroud)
<div id="container">
  <div data-value="1">
    <span>Click me 1</span>
  </div>
  <div data-value="2">
    <span>Click me 2</span>
  </div>
</div>
<div id="messages"></div>
Run Code Online (Sandbox Code Playgroud)

为了使其更加稳健,您可以在继续循环之前检查是否node是,如果是则退出:undefinedwhile

while (!node.dataset || !node.dataset.value) {
  node = node.parentNode;
  if (!node) {
    document.getElementById('messages').innerHTML =
        'Could not find data-value';
    return;
  }
}
Run Code Online (Sandbox Code Playgroud)

while (!node.dataset || !node.dataset.value) {
  node = node.parentNode;
  if (!node) {
    document.getElementById('messages').innerHTML =
        'Could not find data-value';
    return;
  }
}
Run Code Online (Sandbox Code Playgroud)
document.getElementById('container').addEventListener('click', function(e) {
  // Find nearest ancestor with data-value defined
  var node = e.target;
  while (!node.dataset || !node.dataset.value) {
    node = node.parentNode;
    if (!node) {
      document.getElementById('messages').innerHTML = 'Could not find data-value';
      return;
    }
  }
  document.getElementById('messages').innerHTML =
    'you clicked ' + node.dataset.value;
}, false);
Run Code Online (Sandbox Code Playgroud)
#container > div {
  background: red;
}
#container > div > span {
  background: blue;
  color: white;
}
Run Code Online (Sandbox Code Playgroud)