mirror of
https://github.com/zhigang1992/react-native-web.git
synced 2026-03-26 09:14:15 +08:00
[fix] consistency of nativeEvent.location{X,Y} between touch and mouse
Calculate `location{X,Y}` in the same way for both touch and mouse
events. Also defer the call to `getBoundingClientRect` to avoid
unnecessary DOM queries when the data is not used.
This commit is contained in:
@@ -51,8 +51,8 @@ Object {
|
||||
"clientY": 100,
|
||||
"force": false,
|
||||
"identifier": 0,
|
||||
"locationX": 100,
|
||||
"locationY": 100,
|
||||
"locationX": undefined,
|
||||
"locationY": undefined,
|
||||
"pageX": 300,
|
||||
"pageY": 300,
|
||||
"screenX": 400,
|
||||
@@ -63,8 +63,8 @@ Object {
|
||||
],
|
||||
"defaultPrevented": undefined,
|
||||
"identifier": 0,
|
||||
"locationX": 200,
|
||||
"locationY": 200,
|
||||
"locationX": undefined,
|
||||
"locationY": undefined,
|
||||
"pageX": 300,
|
||||
"pageY": 300,
|
||||
"preventDefault": [Function],
|
||||
|
||||
@@ -10,6 +10,15 @@
|
||||
const emptyArray = [];
|
||||
const emptyFunction = () => {};
|
||||
|
||||
const getRect = node => {
|
||||
if (node) {
|
||||
const isElement = node.nodeType === 1 /* Node.ELEMENT_NODE */;
|
||||
if (isElement && typeof node.getBoundingClientRect === 'function') {
|
||||
return node.getBoundingClientRect();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Mobile Safari re-uses touch objects, so we copy the properties we want and normalize the identifier
|
||||
const normalizeTouches = touches => {
|
||||
if (!touches) {
|
||||
@@ -18,25 +27,25 @@ const normalizeTouches = touches => {
|
||||
|
||||
return Array.prototype.slice.call(touches).map(touch => {
|
||||
const identifier = touch.identifier > 20 ? touch.identifier % 20 : touch.identifier;
|
||||
let locationX, locationY;
|
||||
|
||||
const node = touch.target;
|
||||
if (node) {
|
||||
const isElement = node.nodeType === 1 /* Node.ELEMENT_NODE */;
|
||||
if (isElement && typeof node.getBoundingClientRect === 'function') {
|
||||
const rect = node.getBoundingClientRect();
|
||||
locationX = touch.pageX - rect.left;
|
||||
locationY = touch.pageY - rect.top;
|
||||
}
|
||||
}
|
||||
let rect;
|
||||
|
||||
return {
|
||||
_normalized: true,
|
||||
clientX: touch.clientX,
|
||||
clientY: touch.clientY,
|
||||
force: touch.force,
|
||||
locationX: locationX,
|
||||
locationY: locationY,
|
||||
get locationX() {
|
||||
rect = rect || getRect(touch.target);
|
||||
if (rect) {
|
||||
return touch.pageX - rect.left;
|
||||
}
|
||||
},
|
||||
get locationY() {
|
||||
rect = rect || getRect(touch.target);
|
||||
if (rect) {
|
||||
return touch.pageY - rect.top;
|
||||
}
|
||||
},
|
||||
identifier: identifier,
|
||||
pageX: touch.pageX,
|
||||
pageY: touch.pageY,
|
||||
@@ -105,15 +114,27 @@ function normalizeTouchEvent(nativeEvent) {
|
||||
}
|
||||
|
||||
function normalizeMouseEvent(nativeEvent) {
|
||||
let rect;
|
||||
|
||||
const touches = [
|
||||
{
|
||||
_normalized: true,
|
||||
clientX: nativeEvent.clientX,
|
||||
clientY: nativeEvent.clientY,
|
||||
force: nativeEvent.force,
|
||||
locationX: nativeEvent.clientX,
|
||||
locationY: nativeEvent.clientY,
|
||||
identifier: 0,
|
||||
get locationX() {
|
||||
rect = rect || getRect(nativeEvent.target);
|
||||
if (rect) {
|
||||
return nativeEvent.pageX - rect.left;
|
||||
}
|
||||
},
|
||||
get locationY() {
|
||||
rect = rect || getRect(nativeEvent.target);
|
||||
if (rect) {
|
||||
return nativeEvent.pageY - rect.top;
|
||||
}
|
||||
},
|
||||
pageX: nativeEvent.pageX,
|
||||
pageY: nativeEvent.pageY,
|
||||
screenX: nativeEvent.screenX,
|
||||
@@ -143,8 +164,8 @@ function normalizeMouseEvent(nativeEvent) {
|
||||
changedTouches: touches,
|
||||
defaultPrevented: nativeEvent.defaultPrevented,
|
||||
identifier: touches[0].identifier,
|
||||
locationX: nativeEvent.offsetX,
|
||||
locationY: nativeEvent.offsetY,
|
||||
locationX: touches[0].locationX,
|
||||
locationY: touches[0].locationY,
|
||||
pageX: nativeEvent.pageX,
|
||||
pageY: nativeEvent.pageY,
|
||||
preventDefault,
|
||||
|
||||
Reference in New Issue
Block a user