The library for web and native user interfaces.
Fix Clicks in Mobile Safari
This works around a bug with listening to clicks using event delegation on Mobile Safari using an event plugin. NOTE: We don't enable touch events by default, so I don't know if would want to inject this plugin by default. In fact, I'm not sure what our strategy is at all for when to invoke `React.useTouchEvents(true)`.
Tim Yung committed
Jul 22, 2013 at 18:28 UTC
4deb0d619c06e8f0d30f972a6412d65f19b7f921
3 files changed
+68
-2
src/core/ReactDefaultInjection.js
+3
-1
@@ -34,6 +34,7 @@ var ChangeEventPlugin = require('ChangeEventPlugin');
34
var EventPluginHub = require('EventPluginHub');
35
var ReactInstanceHandles = require('ReactInstanceHandles');
36
var SimpleEventPlugin = require('SimpleEventPlugin');
37
+var MobileSafariClickEventPlugin = require('MobileSafariClickEventPlugin');
38
39
function inject() {
40
/**
@@ -49,7 +50,8 @@ function inject() {
50
EventPluginHub.injection.injectEventPluginsByName({
51
'SimpleEventPlugin': SimpleEventPlugin,
52
'EnterLeaveEventPlugin': EnterLeaveEventPlugin,
52
- 'ChangeEventPlugin': ChangeEventPlugin
53
+ 'ChangeEventPlugin': ChangeEventPlugin,
54
+ 'MobileSafariClickEventPlugin': MobileSafariClickEventPlugin
55
});
56
57
ReactDOM.injection.injectComponentClasses({
src/eventPlugins/DefaultEventPluginOrder.js
+2
-1
@@ -35,7 +35,8 @@ var DefaultEventPluginOrder = [
35
keyOf({TapEventPlugin: null}),
36
keyOf({EnterLeaveEventPlugin: null}),
37
keyOf({ChangeEventPlugin: null}),
38
- keyOf({AnalyticsEventPlugin: null})
38
+ keyOf({AnalyticsEventPlugin: null}),
39
+ keyOf({MobileSafariClickEventPlugin: null})
40
];
41
42
module.exports = DefaultEventPluginOrder;
src/eventPlugins/MobileSafariClickEventPlugin.js
new
+63
@@ -0,0 +1,63 @@
1
+/**
2
+ * Copyright 2013 Facebook, Inc.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ *
16
+ * @providesModule MobileSafariClickEventPlugin
17
+ * @typechecks static-only
18
+ */
19
+
20
+"use strict";
21
+
22
+var EventConstants = require('EventConstants');
23
+
24
+var emptyFunction = require('emptyFunction');
25
+
26
+var topLevelTypes = EventConstants.topLevelTypes;
27
+
28
+/**
29
+ * Mobile Safari does not fire properly bubble click events on non-interactive
30
+ * elements, which means delegated click listeners do not fire. The workaround
31
+ * for this bug involves attaching an empty click listener on the target node.
32
+ *
33
+ * This particular plugin works around the bug by attaching an empty click
34
+ * listener on `touchstart` (which does fire on every element).
35
+ */
36
+var MobileSafariClickEventPlugin = {
37
+
38
+ eventTypes: null,
39
+
40
+ /**
41
+ * @param {string} topLevelType Record from `EventConstants`.
42
+ * @param {DOMEventTarget} topLevelTarget The listening component root node.
43
+ * @param {string} topLevelTargetID ID of `topLevelTarget`.
44
+ * @param {object} nativeEvent Native browser event.
45
+ * @return {*} An accumulation of synthetic events.
46
+ * @see {EventPluginHub.extractEvents}
47
+ */
48
+ extractEvents: function(
49
+ topLevelType,
50
+ topLevelTarget,
51
+ topLevelTargetID,
52
+ nativeEvent) {
53
+ if (topLevelType === topLevelTypes.topTouchStart) {
54
+ var target = nativeEvent.target;
55
+ if (target && !target.onclick) {
56
+ target.onclick = emptyFunction;
57
+ }
58
+ }
59
+ }
60
+
61
+};
62
+
63
+module.exports = MobileSafariClickEventPlugin;