2015-07-10 169 views
0

我是JavaScript新手,試圖創建一個遞歸函數來檢查兩個DOM節點是否等效。這個函數似乎對所有東西都返回true,並且不按照我想要的方式檢查DOM。只有節點是等效的。將html節點傳遞給javascript函數

var htmlStrings = ['<div id="one">Some<span>node <em>contents</em> for</span>comparison</div>', '<div id="two">Some<span>node contents for</span>comparison</div>', '<div id="one">Some<span>node <strong>contents</strong> for</span>comparison</div>', '<div id="four">Some<span>node <em>contents</em> for</span>comparison</div>']; 

var div1 = document.createElement('div'); 
div1.innerHTML = htmlStrings[0]; 
document.body.appendChild(div1); 

var div2 = document.createElement('div'); 
div2.innerHTML = htmlStrings[1]; 
document.body.appendChild(div2); 

var div3 = document.createElement('div'); 
div3.innerHTML = htmlStrings[2]; 
document.body.appendChild(div3); 

var div4 = document.createElement('div'); 
div4.innerHTML = htmlStrings[3]; 
document.body.appendChild(div4); 


function nodeEquivalence(node1, node2) { 
    var passed = false; 


     if (node1.nodeType === node2.nodeType) { 
      if ((node1.tagName === node2.tagName && node1.nodeValue === node2.nodeValue)) { 
       passed = true; 
      } 
     } 

     node1 = node1.firstChild; 
     node2 = node2.firstChild; 
     while (node1 && node2) { 
      nodeEquivalence(node1, node2); 
      node1 = node1.nextSibling; 
      node2 = node2.nextSibling; 

     } 

     return passed; 

} 


console.log(nodeEquivalence(div1, div2)); 
console.log(nodeEquivalence(div1, div4)); 
+0

請清除你的問題有點稱號。 http://stackoverflow.com/help/how-to-ask。謝謝! – Sun

回答

0

您正在傳遞字符串,而不是DOM元素。您需要將HTML轉換爲DOM元素。有在

Creating a new DOM element from an HTML string using built-in DOM methods or prototype

描述,你可以做很多的解決方案:

var html1 = '<div id="one">Some<span>node <em>contents</em> for</span>comparison</div>'; 
 
var html2 = '<div id="four">Some<span>node <em>contents</em> for</span>comparison</div>'; 
 
var html3 = '<div id="one">Some<span>node <b>contents</b> for</span>comparison</div>'; 
 

 
var div1 = document.createElement('div'); 
 
div1.innerHTML = html1; 
 
var div2 = document.createElement('div'); 
 
div2.innerHTML = html2; 
 
var div3 = document.createElement('div'); 
 
div3.innerHTML = html3; 
 

 
alert(nodeEquivalence(div1.firstChild, div2.firstChild)); 
 
alert(nodeEquivalence(div1.firstChild, div3.firstChild)); 
 

 

 
function nodeEquivalence (node1, node2) { 
 
    var passed = true; 
 

 
    function test(node1, node2) { 
 
    if ((node1.nodeType === node2.nodeType) && (node1.tagName === node2.tagName || node1.nodeValue === node2.nodeValue) && (node1.childNodes.length === node2.childNodes.length)) { 
 
     passed = true; 
 
    } else { 
 
     passed = false; 
 
    } 
 
    } 
 

 
    node1 = node1.firstChild; 
 
    node2 = node2.firstChild; 
 
    while (passed && node1 && node2) { 
 
    test(node1, node2); 
 
    node1 = node1.nextSibling; 
 
    node2 = node2.nextSibling; 
 

 
    } 
 
    //test(document.body); 
 
    return passed; 
 
};

+0

對不起,我在測試後重新排序了代碼,並沒有注意到您使用了函數賦值而不是函數聲明。我現在修好了。 – Barmar

+0

謝謝。所以這個未定義的問題是用這段代碼解決的,但是當我在chrome開發工具中嘗試它時,它對所有的東西都返回true。只有div1和div4是相等的。更新後的代碼。 – devdropper87

+0

只要兩個節點的子節點數相同,就可以設置「passed = true」。那麼如果孩子不匹配,你從來沒有把它設置爲「假」。 – Barmar

0

使用document.createElement(*tagName*)

Here是一些文檔。

例如,您需要創建兩個元素,將它們都傳入並查看它們是否相等。然後你可以在同一個基礎上兩次。

var newDiv = document.createElement("div"); 
var newSpan = document.createElement("span"); 
0

肯定的,而不是比較2個HTML元素,你簡單地比較兩個字符串。而你的node1,node2將永遠是未定義的。順便說一下,下面這個關於如何比較2個html元素的例子有一些不錯的例子。

How to compare two HTML elements

0

最相關的部分是innerHTML的。大部分信息都在那裏。如果兩個HTML節點的innerHTML相同,則幾乎所有內容都是相同的。比標籤名<input>標籤類型屬性:

function nodeEquivalence(node1, node2) { 
    var equal = false; 
    if (node1.innerHTML === node2.innerHTML) { 
     if (node1.tagName === node2.tagName) { 
      if (node1.type === node2.type) { 
       equal = true; 
      } 
     } 
    } 
    return equal; 
} 

我覺得,這個功能將趕上幾乎所有的案例。

注意,是有差別不大,如果您通過ID類名訪問節點:

var el = document.getElementById(id); 
el.innerHTML 

var el2 = document.getElementsByClassName(className); 
el[0].innerHTML; 

此外,您還可以通過outerHTML比較。當您爲每個HTML節點提供相同的類名時,您將擁有完全相同的內容。

Example

創建HTML元素:

var div = document.createElement("div"); 
var text = document.createTextNode("some text"); 
div.appendChild(text); 
document.body.appendChild(div); 
+0

您的nodeEquivalence函數太複雜。看,我是怎麼做到的。 InnerHTML通常用於設置標籤中的文本。但這不是正確的方法。 InnerHTML就是名稱所說的「HTML中的內容」(整個HTML樹)。要設置文本使用textContent或createTextNode。消息「未定義」出現,因爲您沒有將其附加到文檔中。我會更新我的答案來清除它! – Sun

+0

document.body.appendChild(el)缺失。 – Sun

+0

該功能是正確的! div1中的innerHTML有另一個id,而不是div4。現在創建一個文本節點,並在節點中放入HTML。這不是這個意思。 CreateTextNode是用來創建純文本的! http://jsfiddle.net/zh61e9qb/4/ – Sun