How can we compare two HTML elements whether they are identical or not ?
I tried this thing but no luck
<div class="a"> Hi this is sachin tendulkar </div>
<div class="a"> Hi this is sachin tendulkar </div>
And then on button click, I call a function check()
var divs = $(".a");
alert(divs.length); // Shows 2 here which is correct
if (divs.get(0) == divs.get(1)) alert("Same");
But this is not working. Everything is same in two divs.
Apart from this How can we compare whether two HTML elements are completely idential or not.
Including their innerHTML, className, Id, and their attributes.
Is this doable ?
Actually, I have two HTML documents and I want to remove the identical content from both of them So two elements can have same id.
PS: Updating after Crowder's valuable comments.
If we compare two elements as strings, we would not get a match as their order of attributes may vary So the only option is to iterate through each child attribute and match. I still have to figure out completely working implementation strategy.
(See below for a complete, largely-untested, and certainly un-refactored off-the-cuff solution. But first, the bits and pieces of it.)
Comparing their innerHTML is easy:
if (divs[0].innerHTML === divs[1].innerHTML)
// or if you prefer using jQuery
if (divs.html() === $(divs[1]).html()) // The first one will just be the HTML from div 0
...although you have to ask yourself whether these two elements are equivalent according to your criteria:
<div><span class="foo" data-x="bar">x</span></div>
<div><span data-x="bar" class="foo">x</span></div>
...because their innerHTML will be different (at least on Chrome, and I suspect on most if not all browsers). (More on that below.)
Then you need to compare all of their attributes. As far as I know, jQuery doesn't give you a means of enumerating the attributes, but the DOM does:
function getAttributeNames(node) {
var index, rv, attrs;
rv = [];
attrs = node.attributes;
for (index = 0; index < attrs.length; ++index) {
rv.push(attrs[index].nodeName);
}
rv.sort();
return rv;
}
Then
var names = [getAttributeNames(div[0]), getAttributeNames(div[1])];
if (names[0].length === names[1].length) {
// Same number, loop through and compare names and values
...
}
Note that by sorting the arrays above, I'm assuming the order of their attributes is not significant in your definition of "equivalent." I hope that's the case, because it doesn't seem to be preserved, as I get different results from different browsers when running this test. That being the case, we have to come back to the innerHTML question, because if the order of attributes on the elements themselves is not significant, then presumably the order of attributes on descendant elements shouldn't be significant. If that's the case, you'll need a recursive function that checks the descendants according to your definition of equivalent, and not use innerHTML at all.
But you should be able to put something together from the pieces above to compare two elements according to your criteria.
More to explore:
The question interested me strangely, so I kicked around at it for a while, and came up with the following. It's mostly untested, could use some refactoring, etc., but it should get you most of the way there. I do, again, assume the order of attributes is not significant. The below assumes even the slightest difference in the text is significant.
function getAttributeNames(node) {
var index, rv, attrs;
rv = [];
attrs = node.attributes;
for (index = 0; index < attrs.length; ++index) {
rv.push(attrs[index].nodeName);
}
rv.sort();
return rv;
}
function equivElms(elm1, elm2) {
var attrs1, attrs2, name, node1, node2;
// Compare attributes without order sensitivity
attrs1 = getAttributeNames(elm1);
attrs2 = getAttributeNames(elm2);
if (attrs1.join(",") !== attrs2.join(",")) {
display("Found nodes with different sets of attributes; not equiv");
return false;
}
// ...and values
// unless you want to compare DOM0 event handlers
// (onclick="...")
for (index = 0; index < attrs1.length; ++index) {
name = attrs1[index];
if (elm1.getAttribute(name) !== elm2.getAttribute(name)) {
display("Found nodes with mis-matched values for attribute '" + name + "'; not equiv");
return false;
}
}
// Walk the children
for (node1 = elm1.firstChild, node2 = elm2.firstChild;
node1 && node2;
node1 = node1.nextSibling, node2 = node2.nextSibling) {
if (node1.nodeType !== node2.nodeType) {
display("Found nodes of different types; not equiv");
return false;
}
if (node1.nodeType === 1) { // Element
if (!equivElms(node1, node2)) {
return false;
}
}
else if (node1.nodeValue !== node2.nodeValue) {
display("Found nodes with mis-matched nodeValues; not equiv");
return false;
}
}
if (node1 || node2) {
// One of the elements had more nodes than the other
display("Found more children of one element than the other; not equivalent");
return false;
}
// Seem the same
return true;
}
Live examples: