【问题标题】:How to listen children's events when children stop propagation孩子停止传播时如何监听孩子的事件
【发布时间】:2015-12-22 23:55:04
【问题描述】:

我需要在Document级别观看children的事件,但是如果children使用stopPropagation()方法停止传播,我就无法监听children发生的那些事件。

有人知道更好的方法吗?


编辑:现在我想创建一个 chrome 扩展来监视 DOM 节点事件,但该事件可能会停止传播,并且向所有节点添加额外的侦听器不是一个好习惯。以下示例将显示我的问题。

客户 HTML 片段

<body>
  <input type="button" value="Click Me" id="b">
</body>

客户 javascript

var button = document.querySelector('#b');
button.addEventListener('click', function(e) {
  console.log('Button has been clicked');
  e.stopPropagation();
});

chrome 扩展内容脚本

document.addEventListener('click', function(e) {
  console.log('Node(' + e.target.nodeName + ') has been clicked');
  // this listener will not be invoked because event has been stopped
  // propagation.
});

【问题讨论】:

  • 在这里提问时,最好描述您的真正问题,而不仅仅是您尝试解决的问题。这使阅读您的问题的人可以为您提供您甚至不知道的解决方案。当您只描述您尝试过的解决方案的问题而没有描述真正的问题时,除了您当前尝试创建的解决方案之外,我们几乎无能为力。这被称为XY problem,严重限制了人们对您的帮助程度。'

标签: javascript html events listener stoppropagation


【解决方案1】:

您可以在冒泡之前使用“捕获”来跟踪事件。这篇文章很好地描述了捕获的工作原理(与冒泡相比):Bubbling and capturing

总而言之,除了 IE9 之前的 IE 之外的所有浏览器,都会将事件沿着链向下发送到事件发生的叶子节点,然后再将事件冒泡。普通事件侦听仅侦听实际对象上的事件或传播的事件,但如果将第三个参数设置为 .addEventListener() 为 true,那么它还将侦听沿链向下的事件,document 对象将看到冒泡之前的事件 FIRST 甚至已经开始或被取消。

这是一个有效的 sn-p 演示:

// show output
function log(x) {
    var div = document.createElement("div");
    div.innerHTML = x;
    document.body.appendChild(div);
}

// stop propagation on leaf click
var leaf = document.getElementById("leaf");

leaf.addEventListener("click", function(e) {
  log("leaf message - click in leaf, propagation stopped")
  e.stopPropagation();
}, false);

// capture listen
document.addEventListener("click", function(e) {
  if (e.target === leaf) {
  	log("document message - click in leaf");
  }
}, true);
<div id="topParent">
  <div id="midParent">
    <div id="leaf">
    Click Here
    </div>
  </div>
</div>

【讨论】:

  • 其实,现在我正在开发 chrome 扩展来监控 DOM 事件。给所有 DOM 节点添加事件监听器并不是一个好方法,所以我需要在高级别的地方添加监听器,比如document。但是,事件可能会在其自己的侦听器中停止传播。
  • @nailiebreak - 您正在监控什么事件以及为什么?
  • 我已经更新了我的问题。为什么我需要在document 观看事件是因为我不知道实际的 DOM 节点客户会点击或更改。
  • 抱歉忘记@jfriend00
  • @nailiebreak - 你还没有告诉我们你想要解决的真正问题是什么。你所说的只是你试图在任何地方拦截点击,而不是你真正想要做的事情。您可以从字面上将点击处理程序附加到每个 DOM 元素,并且可以监视 DOM 的更改,但我怀疑如果我们知道实际问题,您是否真的需要走那么远..
猜你喜欢
  • 2016-10-07
  • 2012-02-27
  • 1970-01-01
  • 2019-11-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-18
  • 1970-01-01
相关资源
最近更新 更多