0
# React Tap Event Plugin
1
2
React Tap Event Plugin is a deprecated React plugin that addresses iOS's dreaded 300ms tap delay by injecting a TapEventPlugin into React's event system. It enables developers to use `onTouchTap` and `onTouchTapCapture` events instead of `onClick` to avoid mobile tap delays, though it has been deprecated since React 16.4 as modern browsers have largely resolved the original delay issue.
3
4
## Package Information
5
6
- **Package Name**: react-tap-event-plugin
7
- **Package Type**: npm
8
- **Language**: JavaScript
9
- **Installation**: `npm install react-tap-event-plugin`
10
- **Compatibility**: React 16.0.0 to < 16.4.0
11
- **Status**: Deprecated (use only for legacy browser support)
12
13
## Core Imports
14
15
```javascript
16
var injectTapEventPlugin = require("react-tap-event-plugin");
17
```
18
19
ES6 import (if using transpilation):
20
21
```javascript
22
import injectTapEventPlugin from "react-tap-event-plugin";
23
```
24
25
## Basic Usage
26
27
```javascript
28
var injectTapEventPlugin = require("react-tap-event-plugin");
29
var React = require("react");
30
var ReactDOM = require("react-dom");
31
32
// Inject the plugin once, early in your app lifecycle
33
injectTapEventPlugin();
34
35
var Main = React.createClass({
36
render: function() {
37
return (
38
<a
39
href="#"
40
onTouchTap={this.handleTouchTap}
41
onTouchTapCapture={this.handleTouchTapCapture}
42
onClick={this.handleClick}>
43
Tap Me
44
</a>
45
);
46
},
47
48
handleClick: function(e) {
49
console.log("click", e);
50
},
51
52
handleTouchTap: function(e) {
53
console.log("touchTap", e);
54
},
55
56
handleTouchTapCapture: function(e) {
57
console.log("touchTapCapture", e);
58
}
59
});
60
61
ReactDOM.render(<Main />, document.getElementById("container"));
62
```
63
64
## Capabilities
65
66
### Plugin Injection
67
68
The main functionality is injecting the tap event plugin into React's internal event system.
69
70
```javascript { .api }
71
/**
72
* Injects the TapEventPlugin into React's event system to handle tap events
73
* Must be called once per application lifecycle, before ReactDOM.render()
74
*
75
* @param {Object} strategyOverrides - Optional configuration object
76
* @param {Function} strategyOverrides.shouldRejectClick - Custom click rejection strategy function
77
* @throws {Error} In development mode, throws if called multiple times
78
*/
79
function injectTapEventPlugin(strategyOverrides);
80
```
81
82
**Usage Examples:**
83
84
```javascript
85
// Basic injection with default settings
86
injectTapEventPlugin();
87
88
// Advanced: Custom click rejection strategy
89
injectTapEventPlugin({
90
shouldRejectClick: function(lastTouchEventTimestamp, clickEventTimestamp) {
91
// Always reject clicks (touch-only mode)
92
return true;
93
}
94
});
95
96
// Advanced: Longer click rejection window
97
injectTapEventPlugin({
98
shouldRejectClick: function(lastTouchEventTimestamp, clickEventTimestamp) {
99
// Reject clicks within 1000ms instead of default 750ms
100
return lastTouchEventTimestamp && (clickEventTimestamp - lastTouchEventTimestamp) < 1000;
101
}
102
});
103
```
104
105
### Touch Tap Event Handling
106
107
Once injected, components can use the `onTouchTap` event handler.
108
109
```javascript { .api }
110
/**
111
* Touch tap event properties available in event handlers
112
* This is a SyntheticEvent that follows React's standard event interface
113
*/
114
interface TouchTapEvent {
115
/** Event type - always 'touchTap' */
116
type: string;
117
/** The target element that received the tap */
118
target: HTMLElement;
119
/** Current target (may differ from target during event bubbling) */
120
currentTarget: HTMLElement;
121
/** Event phase (1=capturing, 2=target, 3=bubbling) */
122
eventPhase: number;
123
/** Whether the event bubbles */
124
bubbles: boolean;
125
/** Whether the event can be cancelled */
126
cancelable: boolean;
127
/** Timestamp when the event occurred */
128
timeStamp: number;
129
/** Whether default action was prevented */
130
defaultPrevented: boolean;
131
/** Whether the event is trusted */
132
isTrusted: boolean;
133
134
/** Prevent the default browser behavior */
135
preventDefault(): void;
136
/** Stop event propagation to parent elements */
137
stopPropagation(): void;
138
/** Persist the event object (prevent pooling) */
139
persist(): void;
140
}
141
```
142
143
## Types
144
145
### Strategy Override Configuration
146
147
```javascript { .api }
148
/**
149
* Configuration object for customizing plugin behavior
150
*/
151
interface StrategyOverrides {
152
/**
153
* Custom function to determine if a click event should be rejected
154
* @param lastTouchEventTimestamp - Timestamp of the last touch event (number)
155
* @param clickEventTimestamp - Timestamp of the click event to evaluate (number)
156
* @returns {boolean} - true if click should be rejected, false otherwise
157
*/
158
shouldRejectClick?: (lastTouchEventTimestamp: number, clickEventTimestamp: number) => boolean;
159
}
160
```
161
162
### Default Click Rejection Strategy
163
164
The plugin includes a built-in strategy for rejecting ghost clicks:
165
166
```javascript { .api }
167
/**
168
* Default click rejection strategy
169
* Rejects click events that occur within 750ms of a touch event
170
*
171
* @param {number} lastTouchEvent - Timestamp of last touch event
172
* @param {number} clickTimestamp - Timestamp of click event to evaluate
173
* @returns {boolean} - true if click should be rejected
174
*/
175
function defaultClickRejectionStrategy(lastTouchEvent, clickTimestamp);
176
```
177
178
## Architecture
179
180
The plugin works by:
181
182
1. **Event System Integration**: Injects itself into React's internal EventPluginHub using private APIs
183
2. **Touch Event Detection**: Listens for `touchstart`, `touchend`, `touchcancel`, and `touchmove` events
184
3. **Tap Gesture Recognition**: Detects taps by measuring distance between touch start/end (within 10px threshold)
185
4. **Ghost Click Prevention**: Automatically rejects click events that follow touch events within 750ms
186
5. **Event Synthesis**: Creates synthetic `touchTap` events that bubble through React's event system
187
188
## Error Handling
189
190
The plugin includes several safety mechanisms:
191
192
- **Development Mode Protection**: Throws an invariant error if `injectTapEventPlugin()` is called multiple times
193
- **Production Mode Tolerance**: Silently ignores multiple injection attempts in production
194
- **Event Pooling**: Uses React's event pooling for memory efficiency
195
- **Graceful Degradation**: Falls back to regular click events if touch events are not available
196
197
## Browser Compatibility
198
199
- **Target Browsers**: Primarily iOS Safari and older mobile browsers with 300ms click delay
200
- **Modern Browser Note**: Most modern browsers have eliminated the 300ms delay, making this plugin unnecessary
201
- **React Version**: Compatible with React 16.0.0 to < 16.4.0 only
202
- **Deprecation**: Plugin is deprecated and will not work with React 16.4+
203
204
## Common Use Cases
205
206
1. **Legacy Mobile Support**: Supporting older mobile browsers that still have the 300ms delay
207
2. **Hybrid Apps**: React apps running in WebView containers (like Cordova/PhoneGap)
208
3. **Consistent Touch Response**: Ensuring immediate feedback for touch interactions across all mobile devices
209
4. **Touch-Only Interfaces**: Applications designed exclusively for touch devices