mirror of
https://github.com/zhigang1992/react-native-web.git
synced 2026-04-26 13:35:24 +08:00
**Problem** Browsers tend to fire both touch and mouse events when touch is supported. This causes touchables to fire responder callbacks twice. For example, 'TouchableOpacity' will animate the opacity twice in response to a touch. **Response** If a browser supports touch, don't include the mouse events as dependencies of the responder events. This is not ideal, as some devices support both touch and mouse interactions. This will need to be revisited.
56 lines
2.4 KiB
JavaScript
56 lines
2.4 KiB
JavaScript
// based on https://github.com/facebook/react/pull/4303/files
|
|
|
|
import EventConstants from 'react/lib/EventConstants'
|
|
import EventPluginRegistry from 'react/lib/EventPluginRegistry'
|
|
import ResponderEventPlugin from 'react/lib/ResponderEventPlugin'
|
|
import ResponderTouchHistoryStore from 'react/lib/ResponderTouchHistoryStore'
|
|
import normalizeNativeEvent from './normalizeNativeEvent'
|
|
|
|
const {
|
|
topMouseDown,
|
|
topMouseMove,
|
|
topMouseUp,
|
|
topScroll,
|
|
topSelectionChange,
|
|
topTouchCancel,
|
|
topTouchEnd,
|
|
topTouchMove,
|
|
topTouchStart
|
|
} = EventConstants.topLevelTypes
|
|
|
|
const supportsTouch = ('ontouchstart' in window) || window.DocumentTouch && document instanceof window.DocumentTouch
|
|
|
|
const endDependencies = supportsTouch ? [ topTouchCancel, topTouchEnd ] : [ topMouseUp ]
|
|
const moveDependencies = supportsTouch ? [ topTouchMove ] : [ topMouseMove ]
|
|
const startDependencies = supportsTouch ? [ topTouchStart ] : [ topMouseDown ]
|
|
|
|
/**
|
|
* Setup ResponderEventPlugin dependencies
|
|
*/
|
|
ResponderEventPlugin.eventTypes.responderMove.dependencies = moveDependencies
|
|
ResponderEventPlugin.eventTypes.responderEnd.dependencies = endDependencies
|
|
ResponderEventPlugin.eventTypes.responderStart.dependencies = startDependencies
|
|
ResponderEventPlugin.eventTypes.responderRelease.dependencies = endDependencies
|
|
ResponderEventPlugin.eventTypes.responderTerminationRequest.dependencies = []
|
|
ResponderEventPlugin.eventTypes.responderGrant.dependencies = []
|
|
ResponderEventPlugin.eventTypes.responderReject.dependencies = []
|
|
ResponderEventPlugin.eventTypes.responderTerminate.dependencies = []
|
|
ResponderEventPlugin.eventTypes.moveShouldSetResponder.dependencies = moveDependencies
|
|
ResponderEventPlugin.eventTypes.selectionChangeShouldSetResponder.dependencies = [ topSelectionChange ]
|
|
ResponderEventPlugin.eventTypes.scrollShouldSetResponder.dependencies = [ topScroll ]
|
|
ResponderEventPlugin.eventTypes.startShouldSetResponder.dependencies = startDependencies
|
|
|
|
const originalRecordTouchTrack = ResponderTouchHistoryStore.recordTouchTrack
|
|
|
|
ResponderTouchHistoryStore.recordTouchTrack = (topLevelType, nativeEvent) => {
|
|
// Filter out mouse-move events when the mouse button is not down
|
|
if ((topLevelType === topMouseMove) && !ResponderTouchHistoryStore.touchHistory.touchBank.length) {
|
|
return
|
|
}
|
|
originalRecordTouchTrack.call(ResponderTouchHistoryStore, topLevelType, normalizeNativeEvent(nativeEvent))
|
|
}
|
|
|
|
EventPluginRegistry.injectEventPluginsByName({
|
|
ResponderEventPlugin
|
|
})
|