web-dev-qa-db-ja.com

ミューテーションオブザーバーがテキストの変更を検出しない

MutationObserverがtextContentを使用して行われたテキストの変更を検出しない理由について頭を悩ませています。

HTML

<div id="mainContainer">
  <h1>Heading</h1>
  <p>Paragraph.</p>
</div>

JavaScript

function mutate(mutations) {
  mutations.forEach(function(mutation) {
    alert(mutation.type);
  });
}

jQuery(document).ready(function() {
  setTimeout(function() {
    document.querySelector('div#mainContainer > p').textContent = 'Some other text.';
  }, 2000);

  var target = document.querySelector('div#mainContainer > p')
  var observer = new MutationObserver( mutate );
  var config = { characterData: true, attributes: false, childList: false, subtree: true };

  observer.observe(target, config);
});

上記のスクリプトでは、段落要素のテキストコンテンツは明らかに変更されていますが、MutationObserverはそれを検出しません。

ただし、textContentをinnerHTMLに変更すると、「characterData」が変更されたことが警告されます。

MutationObserverがinnerHTMLを検出するのにtextContentを検出しないのはなぜですか?

これがJSフィドルです:

https://jsfiddle.net/0vp8t8x7/

TextContentをinnerHTMLに変更した場合にのみアラートが表示されることに注意してください。

12
GTS Joe

これは、textContentinnerHTMLとは異なる change をトリガーし、オブザーバー構成がtextContentによって行われた変更を監視するように構成されていないためです。

textContentは、ターゲットの子テキストノードを変更します。 [〜#〜] mdn [〜#〜] 設定textContentによると:

ノードにこのプロパティを設定すると、そのすべての子が削除され、指定された値を持つ単一のテキストノードに置き換えられます。

innerHTMLは要素自体を変更しますが、それはサブツリーです。

したがって、innerHTMLをキャッチするには、構成は次のようになります。

var config = { characterData: true, attributes: false, childList: false, subtree: true };

textContentをキャッチしながら使用:

var config = { characterData: false, attributes: false, childList: true, subtree: false };

デモ:

function mutate(mutations) {
  mutations.forEach(function(mutation) {
    alert(mutation.type);
  });
}

  setTimeout(function() {
    document.querySelector('div#mainContainer > p').textContent = 'some other text.';
  }, 1000);
  
  var target = document.querySelector('div#mainContainer > p')
  var observer = new MutationObserver( mutate );
  var config = { characterData: false, attributes: false, childList: true, subtree: false };

  observer.observe(target, config);
<div id="mainContainer">
  <h1>Heading</h1>
  <p>Paragraph.</p>
</div>
17
Ori Drori