Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to propagate event? InvalidStateError: Failed to execute 'dispatchEvent' on 'EventTarget': The event is already being dispatched

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?

like image 964
Vadorequest Avatar asked Apr 04 '16 16:04

Vadorequest


People also ask

Why does the dispatchevent () method throw unspecified_event_type_err?

The dispatchEvent () method throws UNSPECIFIED_EVENT_TYPE_ERR if the event's type was not specified by initializing the event before the method was called, or if the event's type is null or an empty string.

Which event processing rules apply to events dispatched manually?

The normal event processing rules (including the capturing and optional bubbling phase) also apply to events dispatched manually with dispatchEvent (). event is the Event object to be dispatched.

What is the difference between Native event and dispatchevent?

Unlike "native" events, which are fired by the DOM and invoke event handlers asynchronously via the event loop, dispatchEvent () invokes event handlers synchronously. All applicable event handlers will execute and return before the code continues on after the call to dispatchEvent ().

What is the difference between Native events and event handlers?

The event handlers run on a nested callstack; they block the caller until they complete, but exceptions do not propagate to the caller. Unlike "native" events, which are fired by the DOM and invoke event handlers asynchronously via the event loop , dispatchEvent () invokes event handlers synchronously.


1 Answers

Some event property values disappear when you try to copy the event. That's because many of the event properties have their enumerable property set to false:

Object.defineProperty(event, "target", {     enumerable: false,     writable: true, }); 

That prevents the value of the property from being copied when you clone the event. If you tried Object.keys(evt), the only key that gets returned is isTrusted.

Some properties like target and path only get set after the event is dispatched, and you cannot assign them manually. So if you try to dispatch an event that already has a target, you will hit the error InvalidStateError: Failed to execute 'dispatchEvent' on 'EventTarget': The event is already being dispatched.

That's why you hit this error. You tried to dispatch an event that already got dispatched instead of dispatching a new event.

So when you create your event, you should only copy the properties you care about:

 eventClone = new event.constructor(event.type, propertiesICareAbout)  

where propertiesICareAbout is an object containing the parts of the event you care about, for example propertiesICareAbout = {shiftKey: event.shiftKey}

isTrusted is a property with a specific purpose-- return false if a script has interacted with the event. The property is set to false for exactly that reason. You are using a script to interact with the event and dispatching it via a script. https://developer.mozilla.org/en-US/docs/Web/API/Event/isTrusted

The which property is deprecated and in the process of being dropped, so you shouldn't use that anyway.

React events are probably unrelated to your question. The React synthetic event is delegated and pooled at the top level for performance reasons. If you are dispatching events manually, you should use the native browser method dispatchEvent.

like image 127
Jeremy Gottfried Avatar answered Sep 29 '22 13:09

Jeremy Gottfried