2013-08-01 24 views
5

我剛剛開始閱讀JavaScript,並試圖編寫一個小的遞歸函數,它將搜索給定節點並以字符串形式返回值列表。Javascript - 通過元素遍歷的遞歸函數

我的HTML結構可以是這樣的

<div id="parentfolder">parentfolder1 
    <div class ="item1">item1</div> 
    <div class ="item2">item2</div> 
    <div id="parentfolder">parentfolder2 
     <div class ="item1">item1</div> 
     <div class ="item2">item2</div> 
    </div> 
</div> 

,這裏是我的javascript功能:

function jsoncreator(parentfolderclass){ 
    var jstring = ''; 

    //get first occurance of parent folder 
    var parentfolder = document.getElementById(parentfolderclass); 
    var childnodes = parentfolder.childNodes; 

    for (property in childnodes){ 
     jstring += property+ childnodes[property]; 
     if(childnodes[property] === parentfolderclass){ 
      jsoncreator(parentfolderclass); 
      jstring += childnodes[property].value + '<br>'; 
     } 
     else{ 
      //jstring += childnodes[i].value + '<br>'; 
     } 
    } 
    document.write(jstring); 
} 

所有即時得到的回覆是

0[object Text]1[object HTMLDivElement]2[object Text]3[object HTMLDivElement]4[object Text]5[object HTMLDivElement]6[object Text]length7itemfunction item() { [native code] } 

當我嘗試打印childnodes值,我得到了一堆未定義的回報。

如果有人能解釋我做錯了什麼,我會非常感激。

+0

首先,重複的ID不是有效的HTML。除此之外,你並沒有真正描述返回的數組應該包含什麼。 –

+0

@FabrícioMatté它會返回值的列表作爲字符串 – dudemanbearpig

+0

「值」在他們的文字內容? –

回答

8

你需要做類似如下(遞歸跨瀏覽器)

的Javascript

function walkTheDOM(node, func) { 
    func(node); 
    node = node.firstChild; 
    while (node) { 
     walkTheDOM(node, func); 
     node = node.nextSibling; 
    } 
} 

function textNodeValuesToArray(node) { 
    if (typeof node === "string") { 
     node = document.getElementById(node); 
    } 

    var arrayOfText = []; 

    function pushText(currentNode) { 
     if (currentNode.nodeType === 3) { 
      arrayOfText.push(currentNode.nodeValue); 
     } 
    } 

    walkTheDOM(node, pushText); 

    return arrayOfText; 
} 

console.log(textNodeValuesToArray("parentfolder")); 

jsfiddle

或者使用treewalker

Browser compatibility

Supported by IE9+, FF2+, Chrome 1+, Safari 3+, Opera 9+

的Javascript

function textNodeValuesToArray(node) { 
    if (typeof node === "string") { 
     node = document.getElementById(node); 
    } 

    var arrayOfText = [], 
     treeWalker = document.createTreeWalker(node, NodeFilter.SHOW_TEXT, { 
      acceptNode: function (node) { 
       return NodeFilter.FILTER_ACCEPT; 
      } 
     }, false); 

    while (treeWalker.nextNode()) { 
     arrayOfText.push(treeWalker.currentNode.nodeValue); 
    } 

    return arrayOfText; 
} 

console.log(textNodeValuesToArray("parentfolder")); 

jsfiddle

沒有遞歸和跨瀏覽器會是這樣的

的Javascript

Avoid using labels

Labels are not very commonly used in JavaScript since they make programs harder to read and understand. As much as possible, avoid using labels and, depending on the cases, prefer calling functions or throwing an error.

function walkDOM(root, func) { 
    var node = root; 

    start: while (node) { 
     func(node); 
     if (node.firstChild) { 
      node = node.firstChild; 
      continue start; 
     } 

     while (node) { 
      if (node === root) { 
       break start; 
      } 

      if (node.nextSibling) { 
       node = node.nextSibling; 
       continue start; 
      } 

      node = node.parentNode; 
     } 
    } 
} 

function textNodeValuesToArray(node) { 
    if (typeof node === "string") { 
     node = document.getElementById(node); 
    } 

    var arrayOfText = []; 

    function pushText(currentNode) { 
     if (currentNode.nodeType === 3) { 
      arrayOfText.push(currentNode.nodeValue); 
     } 
    } 

    walkDOM(node, pushText); 

    return arrayOfText; 
} 

console.log(textNodeValuesToArray("parentfolder")); 

jsfiddle

+1

你的回答讓我大惑不解。 – dudemanbearpig

1
<div id="parentfolder">parentfolder1 
    <div class ="item1">item1</div> 
    <div class ="item2">item2</div> 
    <div class="subfolder">parentfolder2 
    <div class ="item1">item1</div> 
    <div class ="item2">item2</div> 
    </div> 
</div> 



var children = document.getElementById('parentfolder').getElementsByClassName('*'); 
var childValues = new Array(); 

for(i=0; i<children.length; i++) { 
    if(children[i].className == 'subfolder') { 
    continue; 
    } else { 
    childValues.push(children[i].innerHTML); 
    } 
} 
+0

你可能是指'getElementsByTagName('*')'中的Tag而不是Class,而'childValues [] = ...'是無效的JS語法。 –

+0

childValues [] = ...是無效的JS語法。是的 - 卡在PHP模式。固定。沒有 - 我的意思是getElementsByClassName('*') –

+1

你確定嗎? http://jsfiddle.net/PnEvM/':)' –