Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix:修复longpress事件误触外层tap事件问题&修正事件pageY,clientY计算 #1792

Merged
merged 7 commits into from
Jan 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useRef, useMemo, RefObject } from 'react'
import { useRef, useMemo, RefObject, useEffect } from 'react'
import { hasOwn, collectDataset } from '@mpxjs/utils'
import { useNavigation } from '@react-navigation/native'
import { omit, extendObject } from './utils'
import eventConfigMap from './event.config'
import {
Expand All @@ -10,15 +11,22 @@ import {
InnerRef,
SetTimeoutReturnType,
LayoutRef,
NativeTouchEvent
NativeTouchEvent,
Navigation
} from './types/getInnerListeners'

const globalEventState = {
needPress: true
}

const getTouchEvent = (
type: string,
event: NativeTouchEvent,
props: Props,
config: UseInnerPropsConfig
config: UseInnerPropsConfig,
navigation: Navigation
) => {
const { y: navigationY = 0 } = navigation?.layout || {}
const nativeEvent = event.nativeEvent
const { timestamp, pageX, pageY, touches, changedTouches } = nativeEvent
const { id } = props
Expand Down Expand Up @@ -49,24 +57,24 @@ const getTouchEvent = (
target,
detail: {
x: pageX,
y: pageY
y: pageY - navigationY
},
touches: touches.map((item) => {
return {
identifier: item.identifier,
pageX: item.pageX,
pageY: item.pageY,
clientX: item.locationX,
clientY: item.locationY
pageY: item.pageY - navigationY,
clientX: item.pageX,
clientY: item.pageY - navigationY
}
}),
changedTouches: changedTouches.map((item) => {
return {
identifier: item.identifier,
pageX: item.pageX,
pageY: item.pageY,
clientX: item.locationX,
clientY: item.locationY
pageY: item.pageY - navigationY,
clientX: item.pageX,
clientY: item.pageY - navigationY
}
}),
persist: event.persist,
Expand Down Expand Up @@ -105,7 +113,8 @@ function handleEmitEvent (
type: string,
oe: NativeTouchEvent,
propsRef: Record<string, any>,
config: UseInnerPropsConfig
config: UseInnerPropsConfig,
navigation: Navigation
) {
events.forEach((event) => {
if (propsRef.current[event]) {
Expand All @@ -114,7 +123,7 @@ function handleEmitEvent (
oe.stopPropagation()
}
propsRef.current[event](
getTouchEvent(type, oe, propsRef.current, config)
getTouchEvent(type, oe, propsRef.current, config, navigation)
)
}
})
Expand All @@ -129,14 +138,14 @@ function checkIsNeedPress (e: NativeTouchEvent, type: 'bubble' | 'capture', ref:
Math.abs(currentPageX - tapDetailInfo.x) > 3 ||
Math.abs(currentPageY - tapDetailInfo.y) > 3
) {
ref.current!.needPress[type] = false
globalEventState.needPress = false
ref.current!.startTimer[type] &&
clearTimeout(ref.current!.startTimer[type] as SetTimeoutReturnType)
ref.current!.startTimer[type] = null
}
}

function handleTouchstart (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: RefObject<InnerRef>, propsRef: Record<string, any>, config: UseInnerPropsConfig) {
function handleTouchstart (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: RefObject<InnerRef>, propsRef: Record<string, any>, config: UseInnerPropsConfig, navigation: Navigation) {
e.persist()
const bubbleTouchEvent = ['catchtouchstart', 'bindtouchstart']
const bubblePressEvent = ['catchlongpress', 'bindlongpress']
Expand All @@ -149,7 +158,7 @@ function handleTouchstart (e: NativeTouchEvent, type: 'bubble' | 'capture', ref:
'capture-bindlongpress'
]
ref.current!.startTimer[type] = null
ref.current!.needPress[type] = true
globalEventState.needPress = true
const nativeEvent = e.nativeEvent
ref.current!.mpxPressInfo.detail = {
x: nativeEvent.changedTouches[0].pageX,
Expand All @@ -159,7 +168,7 @@ function handleTouchstart (e: NativeTouchEvent, type: 'bubble' | 'capture', ref:
type === 'bubble' ? bubbleTouchEvent : captureTouchEvent
const currentPressEvent =
type === 'bubble' ? bubblePressEvent : capturePressEvent
handleEmitEvent(currentTouchEvent, 'touchstart', e, propsRef, config)
handleEmitEvent(currentTouchEvent, 'touchstart', e, propsRef, config, navigation)
const {
catchlongpress,
bindlongpress,
Expand All @@ -173,25 +182,26 @@ function handleTouchstart (e: NativeTouchEvent, type: 'bubble' | 'capture', ref:
captureBindlongpress
) {
ref.current!.startTimer[type] = setTimeout(() => {
ref.current!.needPress[type] = false
handleEmitEvent(currentPressEvent, 'longpress', e, propsRef, config)
// 只要触发过longpress, 全局就不再触发tap
globalEventState.needPress = false
handleEmitEvent(currentPressEvent, 'longpress', e, propsRef, config, navigation)
}, 350)
}
}

function handleTouchmove (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: RefObject<InnerRef>, propsRef: Record<string, any>, config: UseInnerPropsConfig) {
function handleTouchmove (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: RefObject<InnerRef>, propsRef: Record<string, any>, config: UseInnerPropsConfig, navigation: Navigation) {
const bubbleTouchEvent = ['catchtouchmove', 'bindtouchmove']
const captureTouchEvent = [
'capture-catchtouchmove',
'capture-bindtouchmove'
]
const currentTouchEvent =
type === 'bubble' ? bubbleTouchEvent : captureTouchEvent
handleEmitEvent(currentTouchEvent, 'touchmove', e, propsRef, config)
handleEmitEvent(currentTouchEvent, 'touchmove', e, propsRef, config, navigation)
checkIsNeedPress(e, type, ref)
}

function handleTouchend (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: RefObject<InnerRef>, propsRef: Record<string, any>, config: UseInnerPropsConfig) {
function handleTouchend (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: RefObject<InnerRef>, propsRef: Record<string, any>, config: UseInnerPropsConfig, navigation: Navigation) {
// move event may not be triggered
checkIsNeedPress(e, type, ref)
const bubbleTouchEvent = ['catchtouchend', 'bindtouchend']
Expand All @@ -208,19 +218,22 @@ function handleTouchend (e: NativeTouchEvent, type: 'bubble' | 'capture', ref: R
ref.current!.startTimer[type] &&
clearTimeout(ref.current!.startTimer[type] as SetTimeoutReturnType)
ref.current!.startTimer[type] = null
handleEmitEvent(currentTouchEvent, 'touchend', e, propsRef, config)
if (ref.current!.needPress[type]) {
handleEmitEvent(currentTouchEvent, 'touchend', e, propsRef, config, navigation)
if (globalEventState.needPress) {
if (type === 'bubble' && config.disableTap) {
return
}
handleEmitEvent(currentTapEvent, 'tap', e, propsRef, config)
handleEmitEvent(currentTapEvent, 'tap', e, propsRef, config, navigation)
}
}

function handleTouchcancel (
e: NativeTouchEvent,
type: 'bubble' | 'capture',
ref: RefObject<InnerRef>, propsRef: Record<string, any>, config: UseInnerPropsConfig
ref: RefObject<InnerRef>,
propsRef: Record<string, any>,
config: UseInnerPropsConfig,
navigation: Navigation
) {
const bubbleTouchEvent = ['catchtouchcancel', 'bindtouchcancel']
const captureTouchEvent = [
Expand All @@ -232,11 +245,11 @@ function handleTouchcancel (
ref.current!.startTimer[type] &&
clearTimeout(ref.current!.startTimer[type] as SetTimeoutReturnType)
ref.current!.startTimer[type] = null
handleEmitEvent(currentTouchEvent, 'touchcancel', e, propsRef, config)
handleEmitEvent(currentTouchEvent, 'touchcancel', e, propsRef, config, navigation)
}

function createTouchEventHandler (eventName: 'onTouchStart'|'onTouchMove'|'onTouchEnd'|'onTouchCancel', type: 'bubble' | 'capture') {
return (e: NativeTouchEvent, ref: RefObject<InnerRef>, propsRef: Record<string, any>, config: UseInnerPropsConfig) => {
return (e: NativeTouchEvent, ref: RefObject<InnerRef>, propsRef: Record<string, any>, config: UseInnerPropsConfig, navigation: Navigation) => {
const handlerMap = {
onTouchStart: handleTouchstart,
onTouchMove: handleTouchmove,
Expand All @@ -246,7 +259,7 @@ function createTouchEventHandler (eventName: 'onTouchStart'|'onTouchMove'|'onTou

const handler = handlerMap[eventName]
if (handler) {
handler(e, type, ref, propsRef, config)
handler(e, type, ref, propsRef, config, navigation)
}
}
}
Expand All @@ -273,10 +286,6 @@ const useInnerProps = (
bubble: null,
capture: null
},
needPress: {
bubble: false,
capture: false
},
mpxPressInfo: {
detail: {
x: 0,
Expand All @@ -291,6 +300,8 @@ const useInnerProps = (
layoutRef: { current: {} },
disableTap: false
}
const navigation = useNavigation()

const removeProps = [
'children',
'enable-background',
Expand Down Expand Up @@ -332,7 +343,7 @@ const useInnerProps = (
touchEventList.forEach((item) => {
if (finalEventKeys.includes(item.eventName)) {
events[item.eventName] = (e: NativeTouchEvent) =>
item.handler(e, ref, propsRef, config)
item.handler(e, ref, propsRef, config, navigation)
}
})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ type RemoveProps = string[];

type NativeTouchEvent = NativeSyntheticEvent<NativeEvent>

type Navigation = Record<string, any>
interface NativeEvent {
timestamp: number;
pageX: number;
Expand All @@ -36,10 +37,6 @@ interface InnerRef {
bubble: null | ReturnType<typeof setTimeout>;
capture: null | ReturnType<typeof setTimeout>;
};
needPress: {
bubble: boolean;
capture: boolean;
};
mpxPressInfo: {
detail: {
x: number;
Expand All @@ -65,5 +62,6 @@ export {
InnerRef,
LayoutRef,
SetTimeoutReturnType,
DataSetType
DataSetType,
Navigation
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,20 @@ declare module '@mpxjs/utils' {
left: number
right: number
},
layout: {
x: number
y: number
width: number
height: number
},
setOptions: (params: Record<string, any>) => void
} | undefined
}

declare let global: {
__formatValue (value: string): string | number
} & Record<string, any>

declare module '@react-navigation/native' {
export function useNavigation (): any
}
Loading