From 7a57784daf18dacdbbd573f292249b9a773902ea Mon Sep 17 00:00:00 2001 From: Yanzhen Yu Date: Wed, 1 Apr 2026 12:00:00 +0800 Subject: [PATCH] Implement #2: simulate hover event --- package.json | 2 +- src/record/observer.ts | 3 ++- src/replay/index.ts | 19 ++++++++++++++++++- src/types.ts | 1 + 4 files changed, 22 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 24b806e4..6b5f7230 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,6 @@ }, "dependencies": { "mitt": "^1.1.3", - "rrweb-snapshot": "0.5.3" + "rrweb-snapshot": "^0.5.6" } } diff --git a/src/record/observer.ts b/src/record/observer.ts index 0a7de203..d18c55b4 100644 --- a/src/record/observer.ts +++ b/src/record/observer.ts @@ -199,13 +199,14 @@ function initMousemoveObserver(cb: mousemoveCallBack): listenerHandler { }, 500); const updatePosition = throttle( evt => { - const { clientX, clientY } = evt; + const { clientX, clientY, target } = evt; if (!timeBaseline) { timeBaseline = Date.now(); } positions.push({ x: clientX, y: clientY, + id: mirror.getId(target as INode), timeOffset: Date.now() - timeBaseline, }); wrappedCb(); diff --git a/src/replay/index.ts b/src/replay/index.ts index 2fce3a3d..e16fd0dc 100644 --- a/src/replay/index.ts +++ b/src/replay/index.ts @@ -31,11 +31,11 @@ export class Replayer { private iframe: HTMLIFrameElement; private mouse: HTMLDivElement; - private baselineTime: number = 0; private timerIds: number[] = []; private emitter: mitt.Emitter = mitt(); + private baselineTime: number = 0; // record last played event timestamp when paused private lastPlayedEvent: eventWithTime; @@ -260,6 +260,10 @@ export class Replayer { this.later(() => { this.mouse.style.left = `${p.x}px`; this.mouse.style.top = `${p.y}px`; + const target = mirror.getNode(p.id); + if (target) { + this.hoverElements((target as Node) as Element); + } }, p.timeOffset); }); } @@ -308,4 +312,17 @@ export class Replayer { default: } } + + private hoverElements(el: Element) { + this.iframe + .contentDocument!.querySelectorAll('.\\:hover') + .forEach(hoveredEl => { + hoveredEl.classList.remove(':hover'); + }); + let currentEl: Element | null = el; + while (currentEl) { + currentEl.classList.add(':hover'); + currentEl = currentEl.parentElement; + } + } } diff --git a/src/types.ts b/src/types.ts index 4eeae747..c3275322 100644 --- a/src/types.ts +++ b/src/types.ts @@ -159,6 +159,7 @@ export type mousemoveCallBack = (p: mousePosition[]) => void; export type mousePosition = { x: number; y: number; + id: number; timeOffset: number; };