元素事件侦听器回调不适用于自定义事件

eih*_*ero 1 javascript custom-events

元素事件侦听器回调不适用于自定义事件,在以下代码中,将触发文档和窗口事件侦听器,但不会触发元素(在 IE11、FF33 和 Chrome38 上测试,结果相同。)知道吗?我是否误用了自定义事件?

var el = document.getElementById('some-elem');
el.addEventListener('custom', function (e) {
  console.log("Element got event: " + e.type);
}, false, true);

document.addEventListener('custom', function (e) {
  console.log("document got event: " + e.type);
}, false);

window.addEventListener('custom', function (e) {
  console.log("window got event: " + e.type);
}, false);

var evt = document.createEvent('CustomEvent');
evt.initCustomEvent('custom', true, false);
document.dispatchEvent(evt);
Run Code Online (Sandbox Code Playgroud)
<div id="some-elem"></div>
Run Code Online (Sandbox Code Playgroud)

T.J*_*der 5

问题是事件永远不会通过元素,你是在 上触发事件document。相反,在元素上触发它:

var el = document.getElementById('some-elem');
el.addEventListener('custom', function (e) {
  console.log("Element got event: " + e.type);
}, false, true);

document.addEventListener('custom', function (e) {
  console.log("document got event: " + e.type);
}, false);

window.addEventListener('custom', function (e) {
  console.log("window got event: " + e.type);
}, false);

var evt = document.createEvent('CustomEvent');
evt.initCustomEvent('custom', true, false);
el.dispatchEvent(evt); // <=== Change is here
Run Code Online (Sandbox Code Playgroud)
<div id="some-elem"></div>
Run Code Online (Sandbox Code Playgroud)


回复您的评论:

在我的情况下,调度事件的对象与侦听对象不同,这是否意味着只能在同一对象上侦听自定义事件(窗口和文档除外)?

事件必须穿过元素,就像 aclick必须穿过元素才能被click元素上的处理程序看到一样。因此,举例来说,如果你有一个div与事件处理程序就可以了,有一个img 内部div,和你派出的事件img,在处理程序div将触发因为事件冒泡到它(因为你所做的事件空气泡有能力的):

var el = document.getElementById('some-elem');
el.addEventListener('custom', function (e) {
  snippet.log("Element got event: " + e.type);
}, false, true);

document.addEventListener('custom', function (e) {
  snippet.log("document got event: " + e.type);
}, false);

window.addEventListener('custom', function (e) {
  snippet.log("window got event: " + e.type);
}, false);

var evt = document.createEvent('CustomEvent');
evt.initCustomEvent('custom', true, false);
document.getElementById("some-span").dispatchEvent(evt); // <=== Change is here
Run Code Online (Sandbox Code Playgroud)
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script><!-- snippet.js details: http://meta.stackexchange.com/a/242144/134069 -->
<div id="some-elem">
  <span id="some-span"></span>
</div>
Run Code Online (Sandbox Code Playgroud)

来自DOM 事件规范的这张图可能有助于描绘这些东西:

在此处输入图片说明

您调用的元素dispatchEvent是“目标”元素(该td图中的深蓝色)。

  • @eihero:我已经更新了答案以尝试回答该评论。 (2认同)
  • @eihero:正确。事件从父级到子级(捕获阶段),然后从子级到父级(冒泡阶段)。事件永远不会传递给目标的兄弟姐妹。 (2认同)