web页面录屏实现
const options = { childList: true, // 是否调查子节点的变换 subtree: true, // 是否调查全部儿女节点的变换 attributes: true, // 是否调查属性的变换 attributeOldValue: true, // 是否调查属性的变换的旧值 characterData: true, // 是否节点内容或节点文本的变换 characterDataOldValue: true, // 是否节点内容或节点文本的变换的旧值 // attributeFilter: ['class', 'src'] 不在此数组中的属性变革时将被忽略 }; const observer = new MutationObserver((mutationList) => { // mutationList: array of mutation }); observer.observe(document.documentElement, options); 行使起来很简朴,你只必要指定一个根节点和必要监控的一些选项,那么当DOM变革时,在callback函数中就会有一个mutationList,这是一个DOM的变革列表,个中mutation的布局或许为: { type: 'childList', // or characterData、attributes target: <DOM>, // other params } 我们行使一个数组来存放mutation,详细的callback为: const onMutationChange = (mutationsList) => { const getFlowId = (node) => { if (node) { // 新插入的DOM没有标志,以是这里必要兼容 if (!node.__flow) node.__flow = { id: uuid() }; return node.__flow.id; } }; mutationsList.forEach((mutation) => { const { target, type, attributeName } = mutation; const record = { type, target: getFlowId(target), }; switch (type) { case 'characterData': record.value = target.nodeValue; break; case 'attributes': record.attributeName = attributeName; record.attributeValue = target.getAttribute(attributeName); break; case 'childList': record.removedNodes = [...mutation.removedNodes].map(n => getFlowId(n)); record.addedNodes = [...mutation.addedNodes].map((n) => { const snapshot = this.takeSnapshot(n); return { ...snapshot, nextSibling: getFlowId(n.nextSibling), previousSibling: getFlowId(n.previousSibling) }; }); break; } this.records.push(record); }); } function takeSnapshot(node, options = {}) { this.markNodes(node); const snapshot = { vdom: createVirtualDom(node), }; if (options.doctype === true) { snapshot.doctype = document.doctype.name; snapshot.clientWidth = document.body.clientWidth; snapshot.clientHeight = document.body.clientHeight; } return snapshot; } 这内里只必要留意,当你处理赏罚新增DOM的时辰,你必要一次增量的快照,这里如故行使Virtual DOM来记录,在后头播放的时辰,如故天生DOM,插入到父元素即可,以是这里必要参照DOM,也就是兄弟节点。 表单位素监控 上面的MutationObserver并不能监控到input等元素的值变革,以是我们必要对表单位素的值举办非凡处理赏罚。 oninput变乱监听 MDN文档: https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/oninput 变乱工具:select、input,textarea window.addEventListener('input', this.onFormInput, true); onFormInput = (event) => { const target = event.target; if ( target && target.__flow && ['select', 'textarea', 'input'].includes(target.tagName.toLowerCase()) ) { this.records.push({ type: 'input', target: target.__flow.id, value: target.value, }); } } 在window上行使捕捉来捕捉变乱,后头也是这样处理赏罚的,这样做的缘故起因是我们是也许并常常在冒泡阶段阻止冒泡来实现一些成果,以是行使捕捉可以镌汰变乱丢失,其它,像scroll变乱是不会冒泡的,必需行使捕捉。 onchange变乱监听 MDN文档: https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/oninput input变乱没法满意type为checkbox和radio的监控,以是必要借助onchange变乱来监控 window.addEventListener('change', this.onFormChange, true); onFormChange = (event) => { const target = event.target; if (target && target.__flow) { if ( target.tagName.toLowerCase() === 'input' && ['checkbox', 'radio'].includes(target.getAttribute('type')) ) { this.records.push({ type: 'checked', target: target.__flow.id, checked: target.checked, }); } } } onfocus变乱监听 MDN文档: https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onfocus (编辑:湖南网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |