diff --git a/guide.md b/guide.md index e41b4e4d..51a89352 100644 --- a/guide.md +++ b/guide.md @@ -215,6 +215,7 @@ The replayer accepts options as its constructor's second parameter, and it has t | loadTimeout | 0 | timeout of loading remote style sheet | | skipInactive | false | whether to skip inactive time | | showWarning | true | whether to print warning messages during replay | +| showDebug | false | whether to print debug messages during replay | #### Use rrweb-player diff --git a/guide.zh_CN.md b/guide.zh_CN.md index c827909c..8275f4aa 100644 --- a/guide.zh_CN.md +++ b/guide.zh_CN.md @@ -130,13 +130,14 @@ replayer.play(); 可以通过 `new rrweb.Replayer(events, options)` 的方式向 rrweb 传递回放时的配置参数,具体配置如下: -| key | 默认值 | 功能 | -| ------------ | ------------- | ---------------------------- | -| speed | 1 | 回放倍速 | -| root | document.body | 回放时使用的 HTML 元素 | -| loadTimeout | 0 | 加载异步样式表的超时时长 | -| skipInactive | false | 是否快速跳过无用户操作的阶段 | -| showWarning | true | 是否在回放过程中打印警告信息 | +| key | 默认值 | 功能 | +| ------------ | ------------- | ------------------------------- | +| speed | 1 | 回放倍速 | +| root | document.body | 回放时使用的 HTML 元素 | +| loadTimeout | 0 | 加载异步样式表的超时时长 | +| skipInactive | false | 是否快速跳过无用户操作的阶段 | +| showWarning | true | 是否在回放过程中打印警告信息 | +| showDebug | false | 是否在回放过程中打印 debug 信息 | #### 使用 rrweb-player diff --git a/src/replay/index.ts b/src/replay/index.ts index c5966090..ae00635c 100644 --- a/src/replay/index.ts +++ b/src/replay/index.ts @@ -69,6 +69,7 @@ export class Replayer { loadTimeout: 0, skipInactive: false, showWarning: true, + showDebug: false, }; this.config = Object.assign({}, defaultConfig, config); @@ -445,7 +446,7 @@ export class Replayer { const event = new Event(MouseInteractions[d.type].toLowerCase()); const target = mirror.getNode(d.id); if (!target) { - return this.warnNodeNotFound(d, d.id); + return this.debugNodeNotFound(d, d.id); } switch (d.type) { case MouseInteractions.Blur: @@ -490,7 +491,7 @@ export class Replayer { } const target = mirror.getNode(d.id); if (!target) { - return this.warnNodeNotFound(d, d.id); + return this.debugNodeNotFound(d, d.id); } if ((target as Node) === this.iframe.contentDocument) { this.iframe.contentWindow!.scrollTo({ @@ -529,7 +530,7 @@ export class Replayer { } const target = mirror.getNode(d.id); if (!target) { - return this.warnNodeNotFound(d, d.id); + return this.debugNodeNotFound(d, d.id); } try { ((target as Node) as HTMLInputElement).checked = d.isChecked; @@ -577,7 +578,7 @@ export class Replayer { this.mouse.style.top = `${y}px`; const target = mirror.getNode(id); if (!target) { - return this.warnNodeNotFound(d, id); + return this.debugNodeNotFound(d, id); } this.hoverElements((target as Node) as Element); } @@ -621,4 +622,18 @@ export class Replayer { } console.warn(REPLAY_CONSOLE_PREFIX, `Node with id '${id}' not found in`, d); } + + private debugNodeNotFound(d: incrementalData, id: number) { + /** + * There may me some valid scenes of node not being found. + * Because DOM events are macrotask and MutationObserver callback + * is microtask, so events fired on a removed DOM may emit + * snapshots in the reverse order. + */ + if (!this.config.showDebug) { + return; + } + // tslint:disable-next-line: no-console + console.log(REPLAY_CONSOLE_PREFIX, `Node with id '${id}' not found in`, d); + } } diff --git a/src/types.ts b/src/types.ts index 197c7d5e..5c9523bf 100644 --- a/src/types.ts +++ b/src/types.ts @@ -231,6 +231,7 @@ export type playerConfig = { loadTimeout: number; skipInactive: Boolean; showWarning: Boolean; + showDebug: Boolean; }; export type playerMetaData = {