JavaScript 事件和冒泡

标签 javascript dom-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>

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

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

如果单击的区域是 div 区域( fiddle 中的红色部分),则一切正常。当点击来自 div 的子级(例如点击蓝色跨度)时,我如何在不更改事件监听器的情况下获取具有数据值的 data-value

这是 fiddle :http://jsfiddle.net/hgLagy31/1/

最佳答案

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);
#container > div {
  background: red;
}
#container > div > span {
  background: blue;
  color: white;
}
<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>

为了让它更健壮,你可以检查是否nodeundefined在继续 while 之前循环并退出:

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

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);
#container > div {
  background: red;
}
#container > div > span {
  background: blue;
  color: white;
}
<div id="container">
  <div data-value="1">
    <span>Click me 1</span>
  </div>
  <div data-value="2">
    <span>Click me 2</span>
  </div>
  <div>
    <span>Click me 3</span>
  </div>
</div>
<div id="messages"></div>

关于JavaScript 事件和冒泡,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29928203/

相关文章:

javascript - Knockout.js 发送格式奇怪的 JSON 数据

javascript - 在 Angular 8/9 中,我可以确定 app.module.ts 内部的 URL 并在声明模块时使用它吗?

Javascript 或和赋值运算符

javascript - Gulp 任务未连续运行

javascript - 如何识别双击 SELECT 元素中的多个

javascript - 了解 Javascript 中的事件冒泡

javascript - e.preventDefault() 之后的链接无法加载,没有 jQuery

javascript - 使用 JavaScript 检测页面中的任何鼠标事件

javascript - JavaScript 中的事件冒泡

javascript - 单击带有 "i"和 "span"内部问题的链接