El observador de mutación no detecta el cambio de texto

2 minutos de lectura

Me estoy rascando la cabeza en cuanto a por qué MutationObserver no detecta los cambios de texto realizados con 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);
});

En la secuencia de comandos anterior, el contenido de texto del elemento de párrafo cambia claramente, pero MutationObserver no lo detecta.

Sin embargo, si cambia textContent a innerHTML, se le avisará que “characterData” ha cambiado.

¿Por qué MutationObserver detecta innerHTML pero no textContent?

Aquí está el violín JS:

https://jsfiddle.net/0vp8t8x7/

Tenga en cuenta que solo recibirá alertas si cambia textContent a innerHTML.

Avatar de usuario de Ori Drori
Ori Drori

Eso es porque textContent desencadena una diferente cambio que innerHTMLy su configuración de observador no está configurada para observar los cambios realizados por textContent.

textContent cambia el nodo de texto secundario del objetivo. De acuerdo a MDN ajuste textContent:

Establecer esta propiedad en un nodo elimina todos sus elementos secundarios y los reemplaza con un solo nodo de texto con el valor dado.

Tiempo innerHTML cambia el elemento en sí, y su subárbol.

Así que para atrapar innerHTML su configuración debe ser:

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

Mientras para atrapar textContent usar:

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

Manifestación:

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>

  • Supuse que usar textContent para cambiar el texto no activaría la devolución de llamada del observador de mutación, pero en Firefox está activando la devolución de llamada del observador mientras que en Chrome no lo es. ¿Puedes compartir por qué sucede esto?

    – rajá pateriya

    22 de julio de 2020 a las 12:01

¿Ha sido útil esta solución?