fix#71 fix touch event listener and throttle touch move callback

This commit is contained in:
Yanzhen Yu
2026-04-01 12:00:00 +08:00
parent 891b678557
commit 94ca07d45d
4 changed files with 29 additions and 9 deletions

View File

@@ -8,6 +8,7 @@ import {
getWindowWidth, getWindowWidth,
isBlocked, isBlocked,
isAncestorRemoved, isAncestorRemoved,
isTouchEvent,
} from '../utils'; } from '../utils';
import { import {
mutationCallBack, mutationCallBack,
@@ -271,7 +272,7 @@ function initMutationObserver(
return observer; return observer;
} }
function initMousemoveObserver(cb: mousemoveCallBack): listenerHandler { function initMoveObserver(cb: mousemoveCallBack): listenerHandler {
let positions: mousePosition[] = []; let positions: mousePosition[] = [];
let timeBaseline: number | null; let timeBaseline: number | null;
const wrappedCb = throttle(() => { const wrappedCb = throttle(() => {
@@ -285,9 +286,12 @@ function initMousemoveObserver(cb: mousemoveCallBack): listenerHandler {
positions = []; positions = [];
timeBaseline = null; timeBaseline = null;
}, 500); }, 500);
const updatePosition = throttle<MouseEvent>( const updatePosition = throttle<MouseEvent | TouchEvent>(
evt => { evt => {
const { clientX, clientY, target } = evt; const { target } = evt;
const { clientX, clientY } = isTouchEvent(evt)
? evt.changedTouches[0]
: evt;
if (!timeBaseline) { if (!timeBaseline) {
timeBaseline = Date.now(); timeBaseline = Date.now();
} }
@@ -304,7 +308,13 @@ function initMousemoveObserver(cb: mousemoveCallBack): listenerHandler {
trailing: false, trailing: false,
}, },
); );
return on('mousemove', updatePosition); const handlers = [
on('mousemove', updatePosition),
on('touchmove', updatePosition),
];
return () => {
handlers.forEach(h => h());
};
} }
function initMouseInteractionObserver( function initMouseInteractionObserver(
@@ -313,12 +323,14 @@ function initMouseInteractionObserver(
): listenerHandler { ): listenerHandler {
const handlers: listenerHandler[] = []; const handlers: listenerHandler[] = [];
const getHandler = (eventKey: keyof typeof MouseInteractions) => { const getHandler = (eventKey: keyof typeof MouseInteractions) => {
return (event: MouseEvent) => { return (event: MouseEvent | TouchEvent) => {
if (isBlocked(event.target as Node, blockClass)) { if (isBlocked(event.target as Node, blockClass)) {
return; return;
} }
const id = mirror.getId(event.target as INode); const id = mirror.getId(event.target as INode);
const { clientX, clientY } = event; const { clientX, clientY } = isTouchEvent(event)
? event.changedTouches[0]
: event;
cb({ cb({
type: MouseInteractions[eventKey], type: MouseInteractions[eventKey],
id, id,
@@ -328,7 +340,7 @@ function initMouseInteractionObserver(
}; };
}; };
Object.keys(MouseInteractions) Object.keys(MouseInteractions)
.filter(key => Number.isNaN(Number(key))) .filter(key => Number.isNaN(Number(key)) && !key.endsWith('_Departed'))
.forEach((eventKey: keyof typeof MouseInteractions) => { .forEach((eventKey: keyof typeof MouseInteractions) => {
const eventName = eventKey.toLowerCase(); const eventName = eventKey.toLowerCase();
const handler = getHandler(eventKey); const handler = getHandler(eventKey);
@@ -499,7 +511,7 @@ export default function initObservers(o: observerParam): listenerHandler {
o.inlineStylesheet, o.inlineStylesheet,
o.maskAllInputs, o.maskAllInputs,
); );
const mousemoveHandler = initMousemoveObserver(o.mousemoveCb); const mousemoveHandler = initMoveObserver(o.mousemoveCb);
const mouseInteractionHandler = initMouseInteractionObserver( const mouseInteractionHandler = initMouseInteractionObserver(
o.mouseInteractionCb, o.mouseInteractionCb,
o.blockClass, o.blockClass,

View File

@@ -492,6 +492,8 @@ export class Replayer {
} }
break; break;
case MouseInteractions.Click: case MouseInteractions.Click:
case MouseInteractions.TouchStart:
case MouseInteractions.TouchEnd:
/** /**
* Click has no visual impact when replaying and may * Click has no visual impact when replaying and may
* trigger navigation when apply to an <a> link. * trigger navigation when apply to an <a> link.

View File

@@ -184,7 +184,7 @@ export enum MouseInteractions {
Focus, Focus,
Blur, Blur,
TouchStart, TouchStart,
TouchMove, TouchMove_Departed, // we will start a separate observer for touch move event
TouchEnd, TouchEnd,
} }

View File

@@ -151,3 +151,9 @@ export function isAncestorRemoved(target: INode): boolean {
} }
return isAncestorRemoved((target.parentNode as unknown) as INode); return isAncestorRemoved((target.parentNode as unknown) as INode);
} }
export function isTouchEvent(
event: MouseEvent | TouchEvent,
): event is TouchEvent {
return Boolean((event as TouchEvent).changedTouches);
}