Detect changes in HTML code

2

Hi, I would like to know how to detect changes in an HTML structure. For example

<html>
 <div><div>
<html>

Over time that structure will be changing.I would like to know if there is any way to detect the changes..without having to use timeOut in javascript, since requests are made that at one time can last 1000 and in another 2000 Thank you very much!

    
asked by German Mendieta 12.09.2018 в 22:09
source

1 answer

2

You can use the API MutationObserver , define a callback that processes the changes and Then you are told what to observe next to the list of things to observe.

In this example, I'll look at the list of children's nodes, their attributes and changes in the children's tree.

Most of the code shown is to simulate an ajax with promises and variable times, in addition to implementing a console log that does not cover the result.

In addition to adding items and deleting items, there are 2 extra buttons that control the observer to start observing and not observing.

In each item there are 2 more buttons that change an attribute or delete the item.

The observer passes to the callback (each time it detects a change) a list of "mutations", in this list each mutation has a type, and a target or a list of target nodes, the wave is to traverse the mutations and verify the type.

// creamos el observador

const panoptico = new MutationObserver(
  (mutaciones, observer) => {
    for (var m of mutaciones) {
      if (m.type == 'childList') {
        consolog('[espia] Cambió el número de items');
      } else if (m.type == 'attributes') {
        consolog(
          '[espia] El atributo ',
          m.attributeName,
          ' de ',
          m.target.querySelector('h2').innerHTML,
          'fue modificado.');
      }
    }
  }
);

var $dinamico = document.getElementById("dinamico");

// comenzar a observar
document.getElementById("espia").onclick = function() {
  consolog('te estoy viendo');
  panoptico.observe(
    $dinamico, {
      attributes: true,
      childList: true,
      subtree: true
    },
  );
}

// dejar de observar
document.getElementById("desespia").onclick = function() {
  consolog('ya no se que haces');
  panoptico.disconnect();
}

// resto del code ejemplo



// para que el log no tape las cosas
var consolog = function(...cosas) {
  var logs = document.getElementById('logs');
  cosas.forEach((t) => {
    logs.innerHTML += t + " ";
  });
  logs.innerHTML += "\n";
  logs.scrollTop = logs.scrollHeight;
};

let descripciones = ["arbol", "pera", "batata", "semaforo"];
var start = Date.now();

// timeout random por usar el wifi del hotel
var fetchDescripcion = function(id) {
  return new Promise((resolve, reject) => {
    consolog('fetching', id);
    window.setTimeout(() => {
      resolve({
        id: id % descripciones.length,
        descripcion: descripciones[id % descripciones.length],
      });
    }, (Math.random() * 4 + 2) * 1000);
  });
}

var setDescripcion = function(d) {
  consolog('resolve', d.id, d.descripcion);
  var info = document.createElement('div');
  info.className = "info";
  var nombre = document.createElement('h2');
  nombre.innerHTML = "(" + d.id + ") " + d.descripcion;
  var masinfo = document.createElement('p');
  masinfo.innerHTML = "Marca de tiempo: " + (Date.now() - start);

  var marcaMe = document.createElement('button');
  marcaMe.classList.add("btn", "btn-marcar");
  marcaMe.innerHTML = "&#9055;";
  marcaMe.onclick = function(ev) {
    var elem = ev.target.parentNode;
    elem.classList.toggle('marcado');
  }

  var borraMe = document.createElement('button');
  borraMe.classList.add("btn", "btn-borrar");
  borraMe.innerHTML = "&#8416;";
  borraMe.onclick = function(ev) {
    var elem = ev.target.parentNode;
    elem.parentNode.removeChild(elem);
  }
  info.appendChild(nombre);
  info.appendChild(marcaMe);
  info.appendChild(borraMe);
  info.appendChild(masinfo);

  $dinamico.appendChild(info);
}

var getDescripcion = function(id) {
  fetchDescripcion(id).then(x => setDescripcion(x));
}


document.getElementById("pone").onclick = function() {
  for (var i = 0; i < 5; i++) {
    var dId = Math.floor(Math.random() * 20);
    getDescripcion(dId);
  }
}

document.getElementById("saca").onclick = function() {
  while ($dinamico.lastChild) {
    $dinamico.removeChild($dinamico.lastChild);
  }
  start = Date.now();
}
#info {
  position: fixed;
  right: 0;
  top: 25px;
  bottom: 0
}

#logs {
  height: 160px;
  overflow-y: scroll;
  min-width: 50vw;
  background: #fafafa;
  border: 1px solid #ccc;
}

.btn {
  border: 1px solid #ccc;
  border-radius: 5px;
  width: 25px;
  height: 25px;
  line-height: 20px;
  font-size: 14px;
  text-align: center;
  overflow: hidden;
  background: #fff;
  display: inline-block;
  padding: 2px;
  margin: 2px;
  cursor: pointer;
}

.btn-marcar {
  background: #fe0;
  color: #000;
}

.btn-borrar {
  background: #f00;
  color: #fff;
}

.marcado {
  background: #fed;
}

.info {
  border: 1px dashed #000;
  border-radius: 5px;
  padding: 5px;
  margin: 5px 0;
}

h2,
p {
  padding: 0;
  margin: 0 0 5px 0;
}
<html>

<body>
  <nav>
    <button id="pone">agregar 5</button>
    <button id="saca">limpiar</button>

    <button id="espia">empezar a observar</button>
    <button id="desespia">dejar de observar</button>
  </nav>
  <section id="info">
    <PRE id="logs"></PRE>
  </section>
  <section id="dinamico">
    <div>

    </div>
  </section>
</body>

</html>
    
answered by 20.10.2018 / 20:27
source