Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

find difference in two dom elements then make them same

If I have two elements :

Element A :

<div id="myID">
  <div id="a"></div>
  <div id="b"><div id="ba"></div></div>
  <div id="c"><span id="ca"></span></div>
</div>

and Element B :

<div id="myID">
  <div id="a"></div>
  <div id="b"><div id="ba"></div></div>
  <div id="c"><span id="ca"></span></div>
  <div id="d"></div>
</div>

Is it possible to find out that Element B has more children than Element A, then find where is additional element and create it in Element A?

P.S: In real code new element is loaded with Ajax Request, but I don't want to replace all content with loaded content, I need to add only new content and skip existing one.

P.S.S : In my current code I have Md5 checksum to check if new content is not the same as existing, but if new content have only little changes it replaces all content and this is the problem for me.

A piece of my current code :

 window.processResponse = function(data) {
    // Note : "data" is Ajax responseText;
    if(!data) return false;
    var $data = document.createElement("div");
    $data.innerHTML = data;
    var em = $data.getElementsByTagName("*");
    for(var i = 0; i < em.length; i++)
    {
      var parent = sget(em[i].id); // sget function is : document.getElementById
      if(parent) 
      {
        var html = em[i].innerHTML.replace(/(\s)+/gim, "").replace(/(\n|\r\n)+/gim, "");
        var id = em[i].id;
        savedPages[id] = savedPages[id] || [];
        var _md5 = md5(html);
        if(savedPages[id][0] == _md5) continue;
        savedPages[id] = [_md5, getTime()];
        parent.innerHTML = em[i].innerHTML;
      }
      if(em[i].tagName === "SCRIPT") 
      {
        var code = em[i].innerHTML.replace(/(\s)+/gim, "").replace(/(\n|\r\n)+/gim, "");
        var id = em[i].id;
        savedPages[id] = savedPages[id] || [];
        var _md5 = md5(code);
        if(savedPages[id][0] == _md5) continue;
        savedPages[id] = [_md5, getTime()];
        try{eval(em[i].innerHTML)}catch(ex){log(ex)};
      }
    }
  };
like image 215
John Avatar asked Jul 12 '26 15:07

John


1 Answers

So, you can optimize it but it depends also in which browser are you running this code. I assumed the follows:

  • All IDs are unique, and you rely on that. You want to compare basically elements that have the same ID, not the same structure.

  • As you said, all children have IDs, and you want to compare only children – not nested node

  • The elements received from the server have only additional children not less. For removing children, you have to add some other code.

  • Therefore, if you have the same number of children, we assume they're the same (to optimize). If this is not true, then you have to implement the removal of children as well

Said that, I believe that this kind of stuff is more suitable on server side, that should send to the client only the part that are actually modified. That what we do usually – or, if we don't care, replace everything.

  var div = document.createElement('div');
  div.innerHTML = s;

  var root = div.firstChild;
  var children = root.children;

  var documentRoot = document.getElementById(root.id);

  if (documentRoot && documentRoot.children.length < children.length) {
    var node = null;
    var previousNode = null;
    var index = 0;

    while ( node = children[index++] ) {
      var documentNode = document.getElementById(node.id);

      if (!documentNode) {
        if (previousNode)
          documentRoot.insertBefore(node, previousNode.nextSibling);
        else
          documentRoot.insertBefore(node, documentRoot.firstChild);

        documentNode = node;
      }

      previousNode = documentNode;

    }

    previousNode = null;

  } else {
    // probably append as is somewhere

  }
like image 195
ZER0 Avatar answered Jul 14 '26 04:07

ZER0



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!