简体   繁体   English

如何捕获自定义事件?

[英]How to capture custom events?

I am trying to create a custom event and capture that event.我正在尝试创建一个自定义事件并捕获该事件。 Here is my simplified HTML and JavaScript这是我的简化 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>

In this case I get the alert "parent" but then I don't get the child popup.在这种情况下,我收到警报“父母”,但我没有收到子弹出窗口。

However, If I try using already existing event like "click", it works.但是,如果我尝试使用已经存在的事件,如“点击”,它会起作用。

 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>

Is there any way/work around that I can use to capture custom events?有什么方法/解决方法可以用来捕获自定义事件吗?

As Moritz stated, you will need to fire the event on the child, as it is the most-inner element.正如莫里茨所说,您需要在孩子身上触发事件,因为它是最内部的元素。 That way the event bubbles up to each parent.这样,事件就会冒泡到每个父母。 The target of the event will always be the child, but currentTarget of the event will be the current element as it goes up the chain.事件的target将始终是子元素,但事件的currentTarget将是当前元素,因为它沿着链向上移动。

You must make sure that useCapture is true , for the ancestor elements you want the event to be picked-up for.您必须确保useCapturetrue ,对于您希望为其拾取事件的祖先元素。 See: EventTarget.addEventListener .请参阅: EventTarget.addEventListener

useCapture

A Boolean indicating that events of this type will be dispatched to the registered listener before being dispatched to any EventTarget beneath it in the DOM tree.一个Boolean指示此类型的事件将在被分派到 DOM 树中它下面的任何EventTarget之前被分派到已注册的listener器。

Events that are bubbling upward through the tree will not trigger a listener designated to use capture.通过树向上冒泡的事件不会触发指定使用捕获的侦听器。 Event bubbling and capturing are two ways of propagating events that occur in an element that is nested within another element, when both elements have registered a handle for that event.事件冒泡和捕获是传播嵌套在另一个元素中的元素中发生的事件的两种方式,当两个元素都注册了该事件的句柄时。 The event propagation mode determines the order in which elements receive the event.事件传播模式确定元素接收事件的顺序。 See DOM Level 3 Events and JavaScript Event order for a detailed explanation.有关详细说明,请参阅 DOM 级别 3 事件和 JavaScript 事件顺序。 If not specified, useCapture defaults to false .如果未指定, useCapture默认为false

If you remove the useCapture param (the second param) from parent.addEventListener , only the grand-parent will get picked-up, following the child.如果从parent.addEventListener中删除useCapture参数(第二个参数),则只有祖父母会跟随孩子被接走。 It will not break the chain, unless you cancel the event in the child.它不会破坏链条,除非您取消孩子中的事件。

Note: If you are triggering a non-native event, it is preferred to use the CustomEvent constructor.注意:如果要触发非本地事件,最好使用CustomEvent构造函数。 Again, you could just call the constructor directly if you wanted.同样,如果需要,您可以直接调用构造函数。 This is just a browser-safe wrapper.这只是一个浏览器安全的包装器。

 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>

Try dispatching the event on the child node and you'll get both alerts.尝试在子节点上调度事件,您将收到两个警报。

 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