【问题标题】:Observing text change in the entire HTML DOM - How to do this?观察整个 HTML DOM 中的文本变化 - 如何做到这一点?
【发布时间】: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>

我怎样才能做到这一点?

【问题讨论】:

标签: javascript html dom mutation-observers


【解决方案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:stackoverflow.com/q/21311299/2182349
猜你喜欢
  • 2013-10-18
  • 2014-02-15
  • 2016-05-01
  • 1970-01-01
  • 2019-06-30
  • 2020-10-06
  • 2012-07-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多