-
Notifications
You must be signed in to change notification settings - Fork 47k
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
[future uncertain] Add support for pointer events #1389
Conversation
cc @sebmarkbage |
topLevelType === topLevelTypes.topPointerOut || | ||
topLevelType === topLevelTypes.topPointerOver | ||
); | ||
if (!isMouseEvent && !isPointerEvent) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if you move isOverEvent
and isOutEvent
up, I think this can just be if (isOverEvent || isOutEvent)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@spicyj It can be, but I still need to be able to separate isMouseEvent
from isPointerEvent
further down below. I guess we technically can save one unnecessary evaluation if we exit early at line 105. But other than that it should be identical, doesn't hurt though I guess :)
Do you want to add the appropriate pointer events to TapEventPlugin's dependencies? Otherwise I think this looks pretty reasonable. Haven't tested it. |
@steida does this solve your use case? |
@spicyj Hmm I assume you mean because of |
@sebmarkbage Not entirely. Please no PointerEvents Polyfils inside React. It's not as easy as it looks to polyfill such events. It's pretty hard and one can easily broke mobile touch experience with wrong implementation. The beauty of http://www.polymer-project.org/platform/pointer-events.html is its quality, lowlevel-ness and correct behaviour on mobile. For instance, you have to deal with scroll momentum to ignore/filter touches during HW accelerated animation. And more. The only thing React should do is to allow pointer events event types to leverage native behaviour. Deal with it exactly like mouseover, mouseclick etc. plus add their interface. Polymer will fix the rest. |
@steida That's what this is, no polyfill, just the events. |
Then ok. I didn't have a time to test it with Polymer, so I believe you :-) |
topLevelTypes.topPointerCancel, | ||
topLevelTypes.topPointerDown, | ||
topLevelTypes.topPointerMove, | ||
topLevelTypes.topPointerUp, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no trailing comma plz
Update, working in IE11, Leave/Enter broken in all other browsers when polyfilled with handjs. It makes no sense to me, Enter fire when moving red<->green and Leave does not fire at all when leaving red. I've looked up and down EnterLeaveEventPlugin and can't see anything amiss. |
Found the issue:
The way |
After discussing a bit with @spicyj it seems like the best solution might be to actually to polyfill it ourselves (if we're ok with that), it should be a relatively straight-forward and small implementation within React and should be surprisingly well-functioning, as opposed to the universal polyfills. All universal polyfills seem very brittle, has poor browser support, are poorly maintained or doesn't seem to work all that well to begin with. So far, HandJS seems like the only potential polyfill that seems to work consistently with great browser support. It is currently not compatible with React though because of a lack of either to/from-element information in the dispatched events, I've submitted and issue and we'll see what their response is (EDIT: Just got a response, seems like they're considering it). If the issue is resolved it seems like a capable solution, but my initial feeling is that I would probably not be confident in using it as a complete replacement for mouse/touch-events. @sebmarkbage @zpao @spicyj etc, how would you feel about shipping a polyfill for Pointer events in React core given that it stays reasonably small and robust enough? |
Why yet another polyfil? On Fri, Apr 11, 2014 at 1:18 PM, Andreas Svensson
|
@steida Polymer does not support all browsers that React target, so while the implementation seems to work (although not 100% compatible), it's not an option for most people. Also, we would only polyfill if there is no native/polyfill already present, so it would only be a size-cost.
|
For IE8/IE9 click is enough. There is no such touch/tablet devices with IE and touch support. |
And as I already said. Polyfil must be very carefully crafted to not destroy mobile scroll experience. |
@steida Highly subjective seeing as a lack of pointer events would effectively break an application, supporting both mouse (and touch) and pointer events in an application seems like a significant headache to deal with. A reasonable middle-ground could be that we only polyfill with equivalent mouse events if So the way I see it, pointer events walk a very thin line, if you can be sure that it works as it should for everyone then it's extremely beneficial, but if you can't be then it's not really all that useful except for certain edge-case users perhaps. So if it turns out there's a significant population using touch with browsers not listed in |
Update, HandJS responded super fast and have issued 1.3.8 which adds support for I'm still not 100% convinced that we couldn't provide a more suitable polyfill within React. My primary motivator here being that pointer events, just like the updated keyboard events, are superb features and I would hate to see it go unused for any technical reason. |
React's source is already modular (and will stay that way), but there's no easy way to pull out certain parts in a build right now. Hopefully we can get React to a point where it's easier to do custom builds and to choose whether to include or not include certain polyfills, like this hypothetical pointer one. Ideally we could have a cross-browser pointer events shim that works in all browsers React supports while allowing you to bring your own polyfill if you want to use Polymer's or to save bytes if you just don't care about pointer events. |
Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Facebook open source project. Thanks! |
I'm failing to see the issue with adding pointer events to React. If React has its own implementation, and these new pointer events have separate names from the touch and mouse events, then it could only potentially break when people use these new pointer events. I hacked together a polyfill myself that's a jQuery plugin: https://github.com/matthewoates/jQuery.onetap/blob/master/jquery.tap.js Basically, it listens for clicks and touch events. Whenever a touch event happens, we ignore click events for 1 second. That seemed like a solid way to not have multiple events fire for one click/tap. Would a polyfill implemented in this way be acceptable? |
A pointer events polyfill always should not break other events, if there is no bug. I think your 1-second method is currently the best one to prevent multiple event occurrence, while I have found that 700ms is just fine. |
There is great interest but is any of this in React already? It would helpful to see a summary/post of what React can do now with events and then how to augment that with mixins. Frankly, I'm confused about where things are at and are going with events in React. I just want a system where there are not separate calls for mouse and touch. I would also like a system that supports a pen input device, like the Wacom or SPen. Then absolutely I want a system where Myo Armband input can be easily done. I'd like to see an article on the main React site detailing everything React does with events and how different input providers (mouse, touch, stylus, myo, etc) can/will be supported. There has to be a unified approach and solution because there will always be more providers, mouse and touch are just scratching the surface :-) |
@zoomclub We all want something more than just this division between mouse and touch. But as is evident in the latest discussion in #499, the problem is that no one seems decided on what the real solution is. The current design of React AFAIK is to stay as close as possible to HTML5, if PointerEvents become a standard then React will surely have it, but comitting to it without PointEvents becoming a standard is far from a simple decision. So for now I think we'll just have to wait and see what happens to PointerEvents. An idea is to allow any non-standard event-handler specified on a ReactDOM-node to actually be listened to, not just standard events. That would allow people to plug in whatever polyfills/sugars they need, but it may hurt third-party components that would rarely be able to take advantage of it. |
As long as The React synthetic event system can process events for different providers I'll live with it. I'm not so concerned about 3rd party components. I just want to be able to support alternate providers in my own app. This is why in my pre React design I thought that it would be best to parse all events myself and pullout and track the details I'm interested in in a separate object. Then component handlers would use the tracked details and not have to implement the dedicated/limited mouse and separate touch and other provider calls all over the place and trip over themselves trying to manage the mess. Component handlers should be working on their real purpose and not be filled with code that just wrestles with provider/event types. In Flux stores are abstracted, it seems logical to abstract event details from different providers too. This way component handlers just check the state of the tracker object and get on with what they are doing. |
The MyoJS API has arrived and it attaches its hub to the window object. The Myo's frames should be available in any component but I'm not sure if it will be blocked by the React synthetic event system? |
@zoomclub You can always attach listeners yourself using |
@syranide Good to know there are mouse, touch, qwerty and now myo events available :-) |
I'm putting a needs revision label on this until we have more discussion. |
topInput: 'input', | ||
topKeyDown: 'keydown', | ||
topKeyPress: 'keypress', | ||
topKeyUp: 'keyup', | ||
topLostPointerCapture: 'lostpointercapture', | ||
topMouseDown: 'mousedown', | ||
topMouseMove: 'mousemove', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello
Btw Chrome is not adopting it: https://code.google.com/p/chromium/issues/detail?id=162757#c64 |
Unless they see a lot of dev support for it in userland (one comment is no. 128 on that lengthy thread). And it is an official w3c recommendation! http://www.w3.org/blog/news/archives/4430?pk_campaign=feed&pk_kwd=pointer-events-is-a-w3c-recommendation |
flux-reactions is moving in a positive direction with view vs event separation of concerns. PointerEvents would make it ideal. It would be great for react to just manage input providers and event types themselves. UPDATE: There seems to be a growing distaste for Flux and the increasing realization that a powerful event system is at the heart of the flow of data through a React app. Here are more examples of this: http://qiita.com/kimagure/items/22cf4bb2a967fcba376e Looks like Rx and React are a natural pair. |
@iamdustan Interesting. |
@syranide in what way? 😉 |
This is great news! |
@sebmarkbage Now that PointerEvents seem to be gaining traction, should we go ahead and add support to React core? |
I think we need to make a major design choice soon about what we want our event system to be. The browser's naive model is clearly not enough for a lot of use cases (sliding gestures, touch responder negotation, custom bubbling rules such as through abstraction layers instead of DOM layers, etc.). Building our own event system is fundamentally incompatible with other frameworks since the delegation/ownership model doesn't interact well between subtrees. Even if we did it, other frameworks might not and we remain incompatible anyway. Maybe we need two different optional event systems. Yet, we want the out-of-the-box experience to also be nice. We're also backporting some of the event systems from React Native back to the DOM. Essentially it boils down to the fact that the componentization of events is still an unsolved problem since there is still global negotiation needed. Maybe we should support it for the DOM regardless, but I think there is a much bigger discussion to be had about our event strategy. |
@sebmarkbage Definitely, but it seems to me that you'll always have to expose the (almost) raw underlying event APIs, either directly or indirectly. There are millions of targets and none are 100% capable or even agree on the keyboard and mouse interface, so a forced standardized interface seems wholly unrealistic. If users could componentize custom event APIs on-top of that it would be fantastic, but I imagine it's two-fold. Custom event subsystems on a per-subtree/root basis (requires some level of coordination) and event callbacks on a per-node/component basis (totally independent) that depend on either native or custom event subsystems. So one way or another it seems to me that React won't be harmed by exposing PointerEvents the same way all other HTML events are currently exposed, it's just more of the same. |
It would be great to learn more about what is in store for events in React. In the meantime or as an alternative Rx looks like a perfectly logical way of handling events in React apps. The Rx.DOM implementation is robust and is armed with Pointer and Touch events ready to go. See here: https://github.com/Reactive-Extensions/RxJS/blob/master/doc/gettingstarted/events.md |
I’m closing this PR because there doesn’t seem to be enough momentum behind it. I think we should get better at closing PRs that are low on Like anything, it’s a matter of prioritization. I think that a good time to revisit this would be when Chrome supports Pointer events (at the moment it doesn’t). Let’s track any future work on this in #499. I do hope we’ll get this in eventually. Thank you for your work on this! |
This PR adds support for Pointer Events as discussed in facebook#499. It is heavily based on previous work in facebook#1389 and will add most pointer events to the `SimpleEventPlugin` and enter/leave events to `EnterLeaveEventPlugin`. I added a new DOM fixture to test all pointer events and make sure my implementation does indeed work. I tested on Chrome 65 and Firefox 59 without seeing any issues. If you think the fixtures is not necessary for future changes, I'm happy to remove them as well. The only open question is if we want to add a polyfill. For the sake of simplicity, I opted against a polyfill for this PR. However, this work is compatible with [PEP][] (I've verified this behavior in Safari 11 by loading PEP in `fixtures/dom/public/index.html`). [PEP]: https://github.com/jquery/PEP
This PR adds support for Pointer Events as discussed in facebook#499. It is heavily based on previous work in facebook#1389 and will add most pointer events to the `SimpleEventPlugin` and enter/leave events to `EnterLeaveEventPlugin`. I added a new DOM fixture to test all pointer events and make sure my implementation does indeed work. I tested on Chrome 65 and Firefox 59 without seeing any issues. If you think the fixtures is not necessary for future changes, I'm happy to remove them as well. The only open question is if we want to add a polyfill. For the sake of simplicity, I opted against a polyfill for this PR. However, this work is compatible with [PEP][] (I've verified this behavior in Safari 11 by loading PEP in `fixtures/dom/public/index.html`). [PEP]: https://github.com/jquery/PEP
The future of pointer events seem uncertain, this PR should not be accepted until it is decided.
http://www.w3.org/TR/pointerevents/, only IE supports it at the moment it seems, you should be able to polyfill with http://handjs.codeplex.com/
mouseListenerNames
inReactDOMButton
include pointer events? Touch events too? Are there actually any events that you want it to attach when it's disabled?