2012-05-21 5 views
19

두 HTML 요소가 동일하거나 유사한지 비교하려면 어떻게해야합니까? 두 HTML 요소를 비교하는 방법

나는이 일을하지만 행운

<div class="a"> Hi this is sachin tendulkar </div> 
<div class="a"> Hi this is sachin tendulkar </div> 

을 시도 그리고 버튼 클릭에, 나는 기능 검사()

var divs = $(".a"); 
alert(divs.length); // Shows 2 here which is correct 
if (divs.get(0) == divs.get(1)) alert("Same"); 

를 호출하지만이 작동하지 않습니다. 두 사업부 모두 다 동일합니다. 다음은 두 HTML 요소가 완전히 일치하는지 여부를 비교할 수있는 방법입니다. innerHTML, className, Id 및 해당 속성을 포함합니다.

이 것이 가능합니까?

실제로 두 HTML 문서가 있고 두 콘텐츠에서 동일한 콘텐츠를 제거하고 싶습니다. 두 요소가 동일한 ID를 가질 수 있습니다.

추 신 : Crowder의 중요한 의견을 업데이트 한 후 업데이트합니다. 두 요소를 문자열로 비교하면 특성 순서가 다를 수 있으므로 일치하지 않습니다. 유일한 옵션은 각 하위 특성을 반복하고 일치시키는 것입니다. 나는 여전히 완벽하게 작동하는 구현 전략을 파악해야합니다.

+3

* "해당 ID ... 포함"* ID 값이 일치하면 해당 HTML이 유효하지 않습니다. 'id' 값 **은 페이지에서 고유해야합니다 **. –

+0

나는 같은 속성을 가진 두 요소를 다른 순서로 등가 적으로 취급하려고한다고 가정합니다 ...? 예 : '

...
'및 '
...
'이 (가) 일치해야합니까? –

+0

하지만 그들은 동일하지 않습니다 * ... –

답변

26

(완전하고 크게-검증되지 않은, 확실히되지 않은 리팩토링 즉석 솔루션은 아래를 참조하지만 먼저, 비트와 그것의 조각..)

innerHTML가 쉽게 비교 :

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 

... 당신은이 두 가지 요소는 당신의 기준에 따라 동일 여부를 스스로에게 물어 있지만 :

<div><span class="foo" data-x="bar">x</span></div> 
<div><span data-x="bar" class="foo">x</span></div> 

... innerHTML과 다를 수 있으므로 (적어도 Chrome에서는 가능하지만 대부분의 브라우저에서는 그렇지 않을 수 있습니다). (그 아래에 대한 자세한 내용)

그런 다음 모든 속성을 비교해야합니다. 지금까지 내가 아는 한, jQuery를 당신에게 속성을 열거하는 수단을 제공하지 않습니다,하지만 DOM을 수행합니다 위의 배열을 정렬하여, 난 것을

var names = [getAttributeNames(div[0]), getAttributeNames(div[1])]; 
if (names[0].length === names[1].length) { 
    // Same number, loop through and compare names and values 
    ... 
} 

참고 다음

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; 
} 

속성의 순서가 "동급"의 정의에서 중요하지 않다고 가정합니다. this test을 실행할 때 다른 브라우저에서 다른 결과를 얻으므로 유지되지 않는 것 같기 때문에 그런 경우가되기를 바랍니다. 그렇다면 우리는 innerHTML 질문으로 돌아 가야합니다. 왜냐하면 요소 자체의 속성 순서가 중요하지 않은 경우 하위 요소의 속성 순서가 중요하지 않기 때문입니다. 이 해당 케이스 인 인 경우 해당 정의에 따라 하위 항목을 확인하는 재귀 함수가 필요하며 innerHTML은 아예 사용하지 않아야합니다.

하지만 위의 조각에서 무엇인가를 넣어 기준에 따라 두 요소를 비교할 수 있어야합니다.


문제는 이상하게 나에게 관심이, 그래서 쫓겨 :

탐험 잠시 그 주위를 둘러 보았고 다음과 같이 생각해 냈습니다. 대부분 테스트되지 않았고 일부 리팩토링 등을 사용할 수 있지만 대부분의 방법으로 리팩토링해야합니다. 나는 속성의 순서가 중요하지 않다고 가정한다. 아래의 내용은 문자 이 조금이라도 차이가 있다고 가정하면입니다.

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; 
} 

라이브 예 :

+2

감사합니다 T.J.Cowder..Google 솔루션을 사용해보고 어떻게 작동하는지 알려드립니다. 감사합니다. btw – sachinjain024

+0

'outerHTML'을 비교하는 방법은 어떻습니까? –

+1

@Derek : 순서가 다른 동일한 속성을 가진 두 요소가 동일한 'outerHTML' 문자열을 생성한다는 보장은 없습니다. 'innerHTML'을 감싸고 사용하면 작동하지 않습니다; 다른 답변에 대한 내 의견을 참조하십시오. –

2

왜 그것에게 쉬운 방법을하지?

<div id="div1"><div class="a"> Hi this is sachin tendulkar </div></div> 
<div id="div2"><div class="a"> Hi this is sachin tendulkar </div></div> 

if($('#div1').html() == $('#div2').html()) 
    alert('div1 & div2 are the same');   
else 
    alert('div1 & div2 are different'); 

http://jsfiddle.net/5Zwy8/1/

+1

HTML 코드를 편집 할 수 없으므로 요소 주위에 래퍼 div를 배치 할 수 없습니다. – sachinjain024

+2

다른 순서로 동일한 속성을 가진 요소가'innerHTML'에 의해 정렬된다는 보장은 없습니다. –

+0

래퍼를 배치 할 수 없다면, 내가 언급 한 코드 + http://stackoverflow.com/questions/2419749/get-selected-elements-outer-html을 사용할 수 있습니다. 이렇게하면 래퍼가 필요하지 않습니다. – ephemeron

0

방법이 코드를합니까?

var d1 = document.createElement("div"); 
d1.appendChild(divs.get(0)); 
var d2 = document.createElement("div"); 
d2.appendChild(divs.get(1)); 
if (d1.innerHTML == d2.innerHTML) ? 
+2

다른 순서로 동일한 속성을 가진 요소가'innerHTML'에 의해 정렬된다는 보장은 없습니다. –

+1

그리고 실제로 Chrome은 최소한 다음과 같은 속성 순서를 유지합니다. http://jsbin.com/amidip 그래서이 작업은 효과가 없습니다 (물론 속성 순서가 중요하지 않고 다른 순서가 *되어야 함). 일치 없음). –

+1

DOM에서 div를 제거하는 부작용이 있습니다. –

30

당신은 사용할 수 있습니다

element1.isEqualNode(element2); 

를 특정 예에서 :

var divs = $(".a"); 
if (divs.get(0).isEqualNode(divs.get(1))) alert("Same"); 

DOM Level 3 Core Spec

는 모든 세부 사항을 가지고있다. 본질적으로 이는 두 노드가 일치하는 특성, 하위 노드 및 하위 노드 특성을 갖는 경우 true를 반환합니다.

두 요소가 같은 노드 인 경우에만 true를 반환하는 유사한 .isSameNode()가 있습니다. 귀하의 예에서 이들은 동일한 노드는 아니지만 동일한 노드입니다.

+3

이것은 가장 좋은 대답이다. 다른 모든 것은 문자열 또는 속성 비교를 수행하는 것입니다. –

+0

이것은 속성을 고려할 필요가없는 경우에만 좋은 대답입니다. "다음 문자열 속성은 동일합니다 : nodeName, localName, namespaceURI, prefix, nodeValue." 의미 - 다른 속성은 테스트되지 않습니다. –

+1

@sJhonny "NamedNodeMaps 특성이 동일 함"으로 시작하는 항목은 특성이 테스트되었음을 ​​나타냅니다. – Keen

관련 문제