I'm trying to propagate an event from my window.document
to an iframe within this document.
When catching the event in the window.document
I try the following:
event.preventDefault()
(@dispatchTo()).dispatchEvent(event)
# @dispatchTo() returns the reference of `document.querySelector('iframe').contentDocument`
But I get InvalidStateError: Failed to execute 'dispatchEvent' on 'EventTarget': The event is already being dispatched.
I tried preventDefault
and stopPropagation
but none would work. It seems that the event is being dispatched while I try to dispatch it to the iframe document and it fails.
How can I propagate an event to my iframe while catching it from the window.document
?
I do have another eventListener on the iframe for that event, but it doesn't get triggered.
I use React (which has a virtual DOM, it may interfere, it may not, just saying).
I found part-of-a-solution there: https://stackoverflow.com/a/20541207/2391795
And now I'm able to dispatch events from the document to the iframe using this code:
eventClone = new event.constructor(event.type, event)
(@dispatchTo()).dispatchEvent(eventClone)
But since I'm using React, the cloned event isn't equal to the initial event, because React has a kind-of wrapper for events. So I loose many properties, like the which
and isTrusted
, which become false
once cloned.
Is there any way to properly clone a React event?
答案 0 :(得分:0)
当您尝试复制事件时,某些事件属性值会消失。这是因为许多事件属性的可枚举属性都设置为false:
Object.defineProperty(event, "target", {
enumerable: false,
writable: true,
});
这样可以防止在克隆事件时复制属性的值。如果您尝试过Object.keys(evt)
,则唯一返回的密钥是isTrusted
。
某些属性(例如target和path)仅在分派事件之后设置,并且您无法手动分配它们。因此,如果您尝试调度已经具有目标的事件,则会遇到错误InvalidStateError: Failed to execute 'dispatchEvent' on 'EventTarget': The event is already being dispatched
。
这就是为什么您遇到此错误的原因。您尝试调度一个已经调度的事件,而不是调度一个新事件。
因此,当您创建活动时,只应复制您关心的属性:
eventClone = new event.constructor(event.type, propertiesICareAbout)
其中propertiesICareAbout
是一个对象,其中包含您关心的事件的各个部分,例如propertiesICareAbout = {shiftKey: event.shiftKey}
isTrusted
是具有特定用途的属性-如果脚本与事件进行了交互,则返回false
。正是由于这个原因,该属性设置为false
。您正在使用脚本与事件进行交互,并通过脚本进行调度。 https://developer.mozilla.org/en-US/docs/Web/API/Event/isTrusted
which
属性已被弃用,并且正在被删除,因此无论如何您都不应使用该属性。
反应事件可能与您的问题无关。由于性能原因,React合成事件在顶级被委派和合并。如果要手动调度事件,则应使用本机浏览器方法dispatchEvent
。