Preact: Calling `dispatchEvent` on an element no longer triggers `onEvent` handlers under Preact X

Created on 13 Dec 2019  路  3Comments  路  Source: preactjs/preact

I'm up to some funny business in my application where I have a handful of global event handlers bound on the document and then delegated to particular nodes (e.g. the user can hit enter anywhere on the screen to navigate to the next screen, that kind of thing).

In any case it requires me to make use of element.dispatchEvent, which has worked fine in previous versions of Preact, but breaks under 10, and I'm not sure why.

Here's a codepen of it working in 8 and of it not working in 10.1:

let { Component, render, h } = preact;

render(h('input', {
  id: 'lol',
  placeholder: 'Hmmmmm events do not work',
  onEvent (e) { e.target.value = 'Hayyyyy events work' }
}, 'hi'), document.body)

setTimeout(() => {
  document.querySelector('#lol').dispatchEvent(new window.Event('event'))
}, 0)

Any idea why this would have stopped working under X?

Most helpful comment

Indeed indeed. Prior to X, we always lowercased event names, which broke custom events that were not lowercased.

Now, if div.onload is present, we'll transform onLoad to onload. In all other cases we preserve case. This was done to unbreak Preact with Custom Elements and a few DOM events.

All 3 comments

Hey @searls, thanks for opening this issue!

So the issue is that if that event it's not part of the element prototype, the even won't get lowercased. So in your case, the input is actually listening to Event event. So, changing the event name to Event would work.
If you want to keep it consistent, you should use lowercased event pops.

h('input', { onevent() { e.target.value = 'bam!'; } }, 'hi');

The relevant code line is in here: https://github.com/preactjs/preact/blob/master/src/diff/props.js#L99

Hope that helps.

Indeed indeed. Prior to X, we always lowercased event names, which broke custom events that were not lowercased.

Now, if div.onload is present, we'll transform onLoad to onload. In all other cases we preserve case. This was done to unbreak Preact with Custom Elements and a few DOM events.

Yay, thank you!! In my case all it took was converting this:

recipient.dispatchEvent(new window.Event('event'))

To this:

recipient.dispatchEvent(new window.Event('Event'))
Was this page helpful?
0 / 5 - 0 ratings

Related issues

jasongerbes picture jasongerbes  路  3Comments

Zashy picture Zashy  路  3Comments

rajaraodv picture rajaraodv  路  3Comments

paulkatich picture paulkatich  路  3Comments

SabirAmeen picture SabirAmeen  路  3Comments