mirror of
https://github.com/zhigang1992/react-native-web.git
synced 2026-01-12 22:51:09 +08:00
[change] prevent default click behavior when using responder system
Certain HTML elements have a default behaviour (e.g., link navigation)
that can only be prevented in the `click` event handler. The responder
event system doesn't make use of `click` and no callbacks have access to
the `click` event. To prevent unwanted default behaviour, and emulate
the behavior in React Native, the `click` callback will automatically
call `preventDefault()` when the responder system is being used.
The result is that components like `Touchable*` that are overloaded as
web links need to explicitly trigger the link navigation, e.g.,
```
<TouchableOpacity
accessibilityTraits="link"
href={href}
onPress={(e) => {
Linking.openUrl(href);
}}
/>
```
Fix #970
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`modules/createElement it normalizes event.nativeEvent 1`] = `
|
||||
exports[`modules/createElement normalizes event.nativeEvent 1`] = `
|
||||
Object {
|
||||
"_normalized": true,
|
||||
"bubbles": undefined,
|
||||
@@ -23,6 +23,6 @@ Object {
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`modules/createElement it renders different DOM elements 1`] = `<span />`;
|
||||
exports[`modules/createElement renders different DOM elements 1`] = `<span />`;
|
||||
|
||||
exports[`modules/createElement it renders different DOM elements 2`] = `<main />`;
|
||||
exports[`modules/createElement renders different DOM elements 2`] = `<main />`;
|
||||
|
||||
@@ -5,14 +5,14 @@ import React from 'react';
|
||||
import { render, shallow } from 'enzyme';
|
||||
|
||||
describe('modules/createElement', () => {
|
||||
test('it renders different DOM elements', () => {
|
||||
test('renders different DOM elements', () => {
|
||||
let component = render(createElement('span'));
|
||||
expect(component).toMatchSnapshot();
|
||||
component = render(createElement('main'));
|
||||
expect(component).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('it normalizes event.nativeEvent', done => {
|
||||
test('normalizes event.nativeEvent', done => {
|
||||
const onClick = e => {
|
||||
e.nativeEvent.timestamp = 1496876171255;
|
||||
expect(e.nativeEvent).toMatchSnapshot();
|
||||
|
||||
@@ -20,6 +20,9 @@ EventPluginHub.injection.injectEventPluginsByName({
|
||||
ResponderEventPlugin
|
||||
});
|
||||
|
||||
const isModifiedEvent = event =>
|
||||
!!(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey);
|
||||
|
||||
/**
|
||||
* Ensure event handlers receive an event of the expected shape. The 'button'
|
||||
* role – for accessibility reasons and functional equivalence to the native
|
||||
@@ -43,7 +46,9 @@ const eventHandlerNames = {
|
||||
onTouchStartCapture: true
|
||||
};
|
||||
const adjustProps = domProps => {
|
||||
const isButtonRole = domProps.role === 'button';
|
||||
const { onClick, onResponderRelease, role } = domProps;
|
||||
|
||||
const isButtonRole = role === 'button';
|
||||
const isDisabled = AccessibilityUtil.isDisabled(domProps);
|
||||
|
||||
Object.keys(domProps).forEach(propName => {
|
||||
@@ -62,9 +67,20 @@ const adjustProps = domProps => {
|
||||
}
|
||||
});
|
||||
|
||||
// Button role should trigger 'onClick' if SPACE or ENTER keys are pressed
|
||||
// Cancel click events if the responder system is being used. Click events
|
||||
// are not an expected part of the React Native API, and browsers dispatch
|
||||
// click events that cannot otherwise be cancelled from preceding mouse
|
||||
// events in the responder system.
|
||||
if (onResponderRelease) {
|
||||
domProps.onClick = function(e) {
|
||||
if (!e.isDefaultPrevented() && !isModifiedEvent(e.nativeEvent) && !domProps.target) {
|
||||
e.preventDefault();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Button role should trigger 'onClick' if SPACE or ENTER keys are pressed.
|
||||
if (isButtonRole && !isDisabled) {
|
||||
const { onClick } = domProps;
|
||||
domProps.onKeyPress = function(e) {
|
||||
if (!e.isDefaultPrevented() && (e.which === 13 || e.which === 32)) {
|
||||
e.preventDefault();
|
||||
|
||||
Reference in New Issue
Block a user