diff --git a/src/record/index.ts b/src/record/index.ts index 8823a486..e10db65e 100644 --- a/src/record/index.ts +++ b/src/record/index.ts @@ -39,7 +39,10 @@ function record(options: recordOptions = {}) { emit( wrapEvent({ type: EventType.Load, - data: { width: getWindowWidth(), height: getWindowHeight() }, + data: { + width: getWindowWidth(), + height: getWindowHeight(), + }, }), ); const [node, idNodeMap] = snapshot(document); @@ -47,7 +50,18 @@ function record(options: recordOptions = {}) { return console.warn('Failed to snapshot the document'); } mirror.map = idNodeMap; - emit(wrapEvent({ type: EventType.FullSnapshot, data: { node } })); + emit( + wrapEvent({ + type: EventType.FullSnapshot, + data: { + node, + initialOffset: { + left: document.documentElement.scrollLeft, + top: document.documentElement.scrollTop, + }, + }, + }), + ); initObservers({ mutationCb: m => emit( diff --git a/src/types.ts b/src/types.ts index 85b4021f..ae9ed1fd 100644 --- a/src/types.ts +++ b/src/types.ts @@ -26,6 +26,10 @@ export type fullSnapshotEvent = { type: EventType.FullSnapshot; data: { node: serializedNodeWithId; + initialOffset: { + top: number; + left: number; + }; }; }; @@ -199,3 +203,7 @@ export type throttleOptions = { export type listenerHandler = () => void; export type hookResetter = () => void; + +export type playerConfig = { + speed: number; +}; diff --git a/src/utils.ts b/src/utils.ts index 3c92fa70..09284f43 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -40,9 +40,20 @@ export function getIdNodeMap(doc: Document) { return null; } if (node.type === NodeType.Document || node.type === NodeType.Element) { - for (const _n of Array.from(n.childNodes)) { - walk(_n); + let dataStr: string | null = null; + let extraChildIndexes: number[] = []; + if (node.type === NodeType.Element) { + dataStr = (n as Element).getAttribute('data-extra-child-index'); } + if (dataStr) { + extraChildIndexes = JSON.parse(dataStr); + } + n.childNodes.forEach((childNode, index) => { + // skip extra DOM created when rebuild + if (extraChildIndexes.indexOf(index) < 0) { + walk(childNode); + } + }); } } @@ -92,7 +103,10 @@ export function hookSetter( const original = Object.getOwnPropertyDescriptor(target, key); Object.defineProperty(target, key, { set(value) { - d.set!.call(this, value); + // put hooked setter into event loop to avoid of set latency + setTimeout(() => { + d.set!.call(this, value); + }, 0); if (original && original.set) { original.set.call(this, value); }