React: Click events not being triggered with ios touch devices

Created on 2 Sep 2016  路  9Comments  路  Source: facebook/react

Possible bug, I have created this JS Fiddle:
http://jsbin.com/piqolixixi/edit?html,css,js,output

On desktop if i click anywhere (on the components or outside of the components) I get the "Clicked!" alert - which is expected, as on mount I have registered the click event onClick in the Hello component.

If I try the same thing on a ios touch device (im using an ipad mini model A1432, ios 9.3.2)
The click events are not triggered when i touch the react components (Hello and HelloOther).
But if I touch outside of the components the alert comes up.

Whats interesting is that if i add cursor: pointer; css to the components they will then get triggered.
Looks like its some sort of regression around this issue:
https://github.com/facebook/react/issues/2055

I have tried react versions 0.14 to 15.x - same issue

Most helpful comment

This occurs under very specific conditions:

  • have a :hover rule for an element that is clickable. The styles in that rule don't matter, the rule can even be empty.
  • have a CSS3 adjacent sibling rule with a most specific term that matches at least one element in the DOM. It doesn't need to match the entire rule. Again, the rule can even be empty.
  • The clickable element is followed by an element (which could also be wrapped as the first element inside a
    element).

You have a :hover rule for an element that is clickable. The styles in that rule don't matter, the rule can even be empty.
and you have a CSS3 adjacent sibling rule with a most specific term that matches at least one element in the DOM. It doesn't need to match the entire rule. Again, the rule can even be empty.
and the clickable element is followed by an element (which could also be wrapped as the first element inside a element).
In that case, tapping the clickable element (whether that click is a JavaScript onclick handler, or just a simple < a href="..." > does not register. Instead, it applies the :hover style and only on the second tap does it navigate or run the JavaScript. This happens only on Mobile Safari and changing pretty much anything will make the bug disappear

All 9 comments

@jooj123 your click event is not being registered with React's event system. By using document.addEventListener you're registering your own event handler completely separate from React.

React only normalizes and delegates event handlers registered on React components (like <div onClick={this.onClick} />) so you're not getting the normalization that was implemented by React to fix this. This is expected behavior for iOS, see https://github.com/facebook/react/issues/2055#issuecomment-52419353

If you want to capture click events anywhere on the page, try rendering a <div/> that fills the page and attack an onClick handler there.

Its what i figured - its just not ideal to do a full page <div/> in my use case as only parts of the page are react

Yeah, but if you want React to normalize your click event, it needs to be registered via React. React uses it's own top-level listener to delegate events for components, so when you use addEventListener React doesn't know that event handler exists at all.

Going forward is it possible for react to provide an api to cater for this scenario (maybe registers react events on top document level somehow) ? Or is that going against react architectural principles ?

You can see https://github.com/facebook/react/issues/284 for some discussion on that topic

This occurs under very specific conditions:

  • have a :hover rule for an element that is clickable. The styles in that rule don't matter, the rule can even be empty.
  • have a CSS3 adjacent sibling rule with a most specific term that matches at least one element in the DOM. It doesn't need to match the entire rule. Again, the rule can even be empty.
  • The clickable element is followed by an element (which could also be wrapped as the first element inside a element).

You have a :hover rule for an element that is clickable. The styles in that rule don't matter, the rule can even be empty.
and you have a CSS3 adjacent sibling rule with a most specific term that matches at least one element in the DOM. It doesn't need to match the entire rule. Again, the rule can even be empty.
and the clickable element is followed by an element (which could also be wrapped as the first element inside a element).
In that case, tapping the clickable element (whether that click is a JavaScript onclick handler, or just a simple < a href="..." > does not register. Instead, it applies the :hover style and only on the second tap does it navigate or run the JavaScript. This happens only on Mobile Safari and changing pretty much anything will make the bug disappear

@Yogi2001 what is the solution? I cannot find a valid workaround for this specific usecase and your link seems to be dead unfortunately? I have exactly the same specific issue/conditions..

Hope you can help out.

@demanzonderjas
you need to break any of the 3 conditions (break one is enough)
e.g.
remove the hover rule (break condition 1)
remove the adjacent sibling rule (break condition 2)
restructure DOM around that element (break condition 3)

This occurs under very specific conditions:

  • have a :hover rule for an element that is clickable. The styles in that rule don't matter, the rule can even be empty.
  • have a CSS3 adjacent sibling rule with a most specific term that matches at least one element in the DOM. It doesn't need to match the entire rule. Again, the rule can even be empty.
  • The clickable element is followed by an element (which could also be wrapped as the first element inside a element).

You have a :hover rule for an element that is clickable. The styles in that rule don't matter, the rule can even be empty.
and you have a CSS3 adjacent sibling rule with a most specific term that matches at least one element in the DOM. It doesn't need to match the entire rule. Again, the rule can even be empty.
and the clickable element is followed by an element (which could also be wrapped as the first element inside a element).
In that case, tapping the clickable element (whether that click is a JavaScript onclick handler, or just a simple < a href="..." > does not register. Instead, it applies the :hover style and only on the second tap does it navigate or run the JavaScript. This happens only on Mobile Safari and changing pretty much anything will make the bug disappear

After trying what seemed like everything, including all of the above, I found one more case where this would occur, other event(s) was interfering with the click event. I had a mouseenter and mouseleave event that for some reason took some focus away, they certainly shouldn't have, but they did. Maybe that can help someone looking at solving this annoying problem.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

zpao picture zpao  路  3Comments

zpao picture zpao  路  3Comments

framerate picture framerate  路  3Comments

varghesep picture varghesep  路  3Comments

kocokolo picture kocokolo  路  3Comments