繁体   English   中英

如何捕获自定义事件?

[英]How to capture custom events?

我正在尝试创建一个自定义事件并捕获该事件。 这是我的简化 HTML 和 JavaScript

 let parent = document.getElementById('parent'); let child = document.getElementById('child'); parent.addEventListener('custom-event', () => alert("parent"), true); child.addEventListener('custom-event', () => alert("child")); let event = new Event('custom-event'); parent.dispatchEvent(event);
 <div id="parent"> <p id="child"> Hello World </p> </div>

在这种情况下,我收到警报“父母”,但我没有收到子弹出窗口。

但是,如果我尝试使用已经存在的事件,如“点击”,它会起作用。

 let parent = document.getElementById('parent'); let child = document.getElementById('child'); parent.addEventListener('click', () => alert("parent"), true); child.addEventListener('click', () => alert("child"));
 <div id="parent"> <p id="child"> Hello World </p> </div>

有什么方法/解决方法可以用来捕获自定义事件吗?

正如莫里茨所说,您需要在孩子身上触发事件,因为它是最内部的元素。 这样,事件就会冒泡到每个父母。 事件的target将始终是子元素,但事件的currentTarget将是当前元素,因为它沿着链向上移动。

您必须确保useCapturetrue ,对于您希望为其拾取事件的祖先元素。 请参阅: EventTarget.addEventListener

useCapture

一个Boolean指示此类型的事件将在被分派到 DOM 树中它下面的任何EventTarget之前被分派到已注册的listener器。

通过树向上冒泡的事件不会触发指定使用捕获的侦听器。 事件冒泡和捕获是传播嵌套在另一个元素中的元素中发生的事件的两种方式,当两个元素都注册了该事件的句柄时。 事件传播模式确定元素接收事件的顺序。 有关详细说明,请参阅 DOM 级别 3 事件和 JavaScript 事件顺序。 如果未指定, useCapture默认为false

如果从parent.addEventListener中删除useCapture参数(第二个参数),则只有祖父母会跟随孩子被接走。 它不会破坏链条,除非您取消孩子中的事件。

注意:如果要触发非本地事件,最好使用CustomEvent构造函数。 同样,如果需要,您可以直接调用构造函数。 这只是一个浏览器安全的包装器。

 let grandParent = document.getElementById('x-grand-parent'); let parent = document.getElementById('x-parent'); let child = document.getElementById('x-child'); grandParent.addEventListener('custom-event', (e) => console.log(e.currentTarget.id), true); parent.addEventListener('custom-event', (e) => console.log(e.currentTarget.id), true); child.addEventListener('custom-event', (e) => console.log(e.currentTarget.id)); triggerCustomEvent(child, 'custom-event'); function triggerCustomEvent(el, eventName, options) { let opts = Object.assign({ canBubble: true, cancelable: true, detail: {} }, options); let event = null; if (window.CustomEvent && typeof window.CustomEvent === 'function') { event = new CustomEvent(eventName, { detail: opts.detail }); } else { event = document.createEvent('CustomEvent'); event.initCustomEvent(eventName, opts.canBubble, opts.cancelable, opts.detail); } el.dispatchEvent(event); }
 <div id="x-grand-parent"> <div id="x-parent"> <p id="x-child"> Hello World </p> </div> </div>

尝试在子节点上调度事件,您将收到两个警报。

 let parent = document.getElementById('parent'); let child = document.getElementById('child'); parent.addEventListener('custom-event', () => alert("parent"), true); child.addEventListener('custom-event', () => alert("child")); let event = new Event('custom-event'); child.dispatchEvent(event);
 <div id="parent"> <p id="child"> Hello World </p> </div>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM