如何比较两个HTML元素 [英] How to compare two HTML elements

查看:90
本文介绍了如何比较两个HTML元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们如何比较两个HTML元素是否相同?



我试过这个东西,但没有运气

 < div class =a>您好,这是sachin tendulkar< / div> 
< div class =a>您好,这是sachin tendulkar< / div>

然后在按钮上单击,我调用一个函数check()

  var divs = $(。a); 
alert(divs.length); //在这里显示2是正确的
if(divs.get(0)== divs.get(1))alert(Same);

但这不起作用。两个div里的一切都一样。
除此之外我们如何比较两个HTML元素是否完全是理想的。
包括它们的innerHTML,className,Id及其属性。



这是可行的吗?实际上,我有两个HTML文档,我想从中删除相同的内容他们两人所以两个元素可以有相同的ID。



PS:克劳德的宝贵意见后更新。
如果我们比较两个元素作为字符串,我们不会得到一个匹配,因为他们的属性顺序可能会有所不同。所以唯一的选择是遍历每个子属性并进行匹配。我仍然需要弄清楚完整的工作实施策略。 解决方案

而且首先是零碎的)



比较他们的 innerHTML 很简单:

  if(divs [0] .innerHTML === divs [1] .innerHTML)
//或者如果您更喜欢使用jQuery
if(divs.html()=== $(divs [1])。html())//第一个将是来自div的HTML 0

...尽管您必须问自己,这两个元素是否相等您的标准:

 < div>< span class =foodata-x =bar> x< /跨度>< / DIV> 
< div>< span data-x =barclass =foo> x< / span>< / div>

...因为它们的 innerHTML 将会不同(至少在Chrome上,我怀疑大多数,如果不是所有的浏览器)。 (更多关于下面的内容。)



然后你需要比较它们的所有属性。据我所知,jQuery并没有给你一个枚举属性的方法,但是DOM确实:

pre $ function $ getAttributeNames (节点){
var index,rv,attrs;

rv = [];
attrs = node.attributes; (index = 0; index< attrs.length; ++ index){
rv.push(attrs [index] .nodeName);
;
}
rv.sort();
return rv;

然后

  var names = [getAttributeNames(div [0]),getAttributeNames(div [1])]; 
if(names [0] .length === names [1] .length){
//相同的数字,循环并比较名称和值
...
}

请注意,通过对上面的数组进行排序,我假设它们的属性顺序并不重要在你的等价的定义中。我希望是这样,因为它似乎没有被保留下来,因为当运行这个测试。既然如此,我们必须回到 innerHTML 的问题,因为如果元素本身的属性顺序并不重要,那么推测可能是后裔属性的顺序元素不应该是重要的。如果那么,您需要一个递归函数,根据您的等价定义检查后代,而不是使用 innerHTML



但是,您应该可以根据您的标准将以上各部分放在一起以便比较两个元素。



更多探索:






奇怪地感兴趣,所以我在这里踢了一会儿,然后提出了以下几点。它大部分都是未经测试的,可以使用一些重构等,但它应该能让你获得大部分的方式。我再次假设属性的顺序并不重要。下面假设文本中的细微差别是显着的。

  function getAttributeNames(node){ 
var index,rv,attrs;

rv = [];
attrs = node.attributes; (index = 0; index< attrs.length; ++ index){
rv.push(attrs [index] .nodeName);
;
}
rv.sort();
return rv;


函数equivElms(elm1,elm2){
var attrs1,attrs2,name,node1,node2;

//比较没有订单敏感性的属性
attrs1 = getAttributeNames(elm1);
attrs2 = getAttributeNames(elm2);
if(attrs1.join(,)!== attrs2.join(,)){
display(找到具有不同属性集合的节点;不是equiv);
返回false;
}

// ...和值
//除非您想比较DOM0事件处理程序
//(onclick =...)
for(index = 0; index< attrs1.length; ++ index){
name = attrs1 [index];
if(elm1.getAttribute(name)!== elm2.getAttribute(name)){
display(找到与属性值不匹配的节点'+ name +'; not equiv );
返回false; (节点1 = elm1.firstChild,node2 = elm2.firstChild;
node1&&< b


$ b) node2;
node1 = node1.nextSibling,node2 = node2.nextSibling){
if(node1.nodeType!== node2.nodeType){
display(Found found of different types; not当量);
返回false;

if(node1.nodeType === 1){//元素
if(!equivElms(node1,node2)){
return false;


else if(node1.nodeValue!== node2.nodeValue){
display(Found nodes with mis-matching nodeValues; not equiv);
返回false;


if(node1 || node2){
//其中一个元素的节点多于另一个元素的
显示(找到更多的子元素元素比另一个;不等效);
返回false;
}

//看起来相同的
返回true;

$ / code>

现场示例:


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:

这篇关于如何比较两个HTML元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆