观察整个 HTML DOM 中的文本变化 - 如何做到这一点?
Posted
技术标签:
【中文标题】观察整个 HTML DOM 中的文本变化 - 如何做到这一点?【英文标题】:Observing text change in the entire HTML DOM - How to do this? 【发布时间】:2021-04-06 15:53:44 【问题描述】:我想监控完整的 html 以进行以下更改:
每当标签中的“文本”发生变化时 每当添加标签中的“文本”时 每当添加带有“文本”的新标签时所以,我只想监视 DOM 中的文本更改。可能是因为添加了带有一些文本的新节点,可能是因为某些现有标签中的文本从 a
更改为 b
,或者可能是因为在其他空标签 <h1></h1> --> <h1>hello</h1>
中添加了文本
我怎么能这样做?我尝试了 MutationObserver,但我发现它非常混乱,我无法正确使用它。我想检测新添加的文本并通过转换函数对其进行转换。比如,
<span>apple</span>
被添加,它将被转换为:
const transformedText = transform("apple");
// update the text
<span>transformedText</span>
这是我尝试过的:
const config =
attributes: false,
childList: true,
subtree: true,
characterData: true,
characterDataOldValue: true
;
const callback = function (mutationsList, observer)
// Use traditional 'for loops' for IE 11
const dict = transformDictionary();
for (const mutation of mutationsList)
if (mutation.type === "childList")
for (const node of mutation.addedNodes)
if (node.setAttribute)
// TRANSFORM
if (mutation.target)
// TRANSFORM
else if (mutation.type === "characterDataOldValue")
console.log(mutation);
else if (mutation.type === "characterData")
;
const o = new MutationObserver(callback).observe(document.body, config);
但是对于不是文本节点的节点,似乎有很多触发器。例如,一个节点也会收到一个触发器,例如这个完整的div
:
<div>
wow
<div>
ok
<p>
<span>hello</span>
</p>
</div>
</div>
我怎样才能做到这一点?
【问题讨论】:
How to change the HTML content as it's loading on the page 【参考方案1】:"use strict";
const NOT_AVAILABLE = "NOT AVAILABLE";
let dictionary = new Map();
dictionary.set("apple", "transformedAppleText");
dictionary.set("pickle", "transformedPickleText");
dictionary.set("pumpkin", "transformedPumpkinText");
const callback = function(mutationsList, observer)
const transform = (node) =>
let transformedText = dictionary.get(node.textContent);
node.textContent = transformedText !== undefined ? transformedText : NOT_AVAILABLE;
;
for (let mutation of mutationsList)
if (mutation.type === "childList")
for (let node of mutation.addedNodes)
// Thanks to:https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType
if (node.nodeType === Node.TEXT_NODE)
transform(node);
else if (node.childNodes.length > 0)
for (let childNode of node.childNodes)
if (childNode.nodeType === Node.TEXT_NODE)
transform(childNode);
// clear out any changes made during this function - prevents bouncing
observer.takeRecords();
;
const config =
childList: true,
subtree: true
;
const o = new MutationObserver(callback).observe(document.getElementById("main"), config);
// DOM updates for testing
const div = document.createElement("div");
document.body.appendChild(div);
const apple = document.createTextNode("apple");
const p = document.createElement("p");
p.id = "apple";
p.appendChild(apple);
document.getElementById("div").appendChild(p);
const orange = document.createTextNode("orange");
const p2 = document.createElement("p");
p2.appendChild(orange);
document.getElementById("div").appendChild(p2);
document.getElementById("span").textContent = "pumpkin";
setTimeout(() =>
document.getElementById("apple").textContent = "pickle", 4000);
<main id="main">
<h1>Demo</h1>
<p>New line</p>
<div id="div">
<p>Some text</p>
<div>cat
<span id="span"></span>
</div>
</div>
</main>
.takeRecords
方法读取队列中的所有突变并返回它们。它还清空队列。我用它来丢弃由观察者中的代码更改文本引起的任何突变。 https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver/takeRecords
【讨论】:
你能解释一下takeRecords
的用法吗?没看懂。
另外,为什么在transform
函数中使用node.textContent
?为什么不只是node.nodeValue
?
我使用 textContent 因为它是文本翻译。
和node.nodeValue
有什么区别?你能解释一下takeRecords
吗?
textContent 与 nodeValue:***.com/q/21311299/2182349以上是关于观察整个 HTML DOM 中的文本变化 - 如何做到这一点?的主要内容,如果未能解决你的问题,请参考以下文章