Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feature request] support capturing event handlers #1435

Open
acheronfail opened this issue Jan 16, 2019 · 5 comments
Open

[feature request] support capturing event handlers #1435

acheronfail opened this issue Jan 16, 2019 · 5 comments

Comments

@acheronfail
Copy link
Contributor

acheronfail commented Jan 16, 2019

React has support for defining event handlers that use capturing rather than bubbling:

To register an event handler for the capture phase, append Capture to the event name; for example, instead of using onClick, you would use onClickCapture to handle the click event in the capture phase.

I'd like for this to exist in Inferno too.
If #1434 is merged, then adding this functionality won't be too difficult since we'll be using addEventListener and we can change the args if "Capture" is found at the end of the event prop.

What are people's thoughts?

@Havunen
Copy link
Member

Havunen commented Jan 16, 2019

It would also be great to support passive event listeners. However I don't know how React defines Passive and Capture ... Also what happens when browser vendors extend the options. It would be better to have future proof API and put that into inferno-compat

@acheronfail
Copy link
Contributor Author

There's an interesting discussion about this in React here: facebook/react#6436

@trueadm
Copy link
Member

trueadm commented Jan 16, 2019

I can expand on capture events for React (I'm in the middle of looking at the event system for React). React allows most events to work in the "capture" phase by appending "Capture" to the end of the prop name, i.e. onClickCapture.

A captured event gets triggered in the opposite ordering of bubbling (so before bubbled events get fired). React collects the DOM node hierarchy and traverses through them in two phases – capture first, then bubble. This is kind of like how Inferno works already, except Inferno only has one phase – bubbling. To make this work, you'd need to collect the DOM nodes [document > A > B > C] and then loop through them in those orders.

@acheronfail
Copy link
Contributor Author

After thinking about this a little more I think a future proof API is actually a good idea. I'm not sure React's way of appending "Capture" is the best way to do this.

In the thread I linked above there were a few different suggestions, some which stood out to me were:

import { eventHandler } from 'inferno';

<div onClick={eventHandler(listener, options}} />
<div onClick={{ handler, options }} />

In both cases if there are future changes to the addEventListener API then these should be future proof.

@trueadm
Copy link
Member

trueadm commented Jan 16, 2019

Agreed, this is something we're looking at too. I thought I'd add what React does right now anyway for context. A better API might be to leverage a JSX node that the compiler can optimize away at build time:

import { Event } from 'inferno';

<Event type="click" bubbles={false} passive={true} on={e => ...}>
  <div>Hello world</div>
</Event>

This would improve performance and reduce code size. The event can also fire for multiple children, which makes it extremely powerful and far more composable than attaching props to a VNode. In fact you could remove the controlled components system entire.

const onChange = (value, key) => {
  this.setState({[key]: value});
}

<ChangeEvent type="value" on={onChange}>
  <input key="name" type="text" value={this.state.name} />
  <input key="age" type="text" value={this.state.age} />
</ChangeEvent>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

3 participants