2013-08-01 30 views
5

Ho appena iniziato a leggere su JavaScript e sto provando a scrivere una piccola funzione ricorsiva che cercherebbe attraverso determinati nodi e restituirà una lista di valori come una stringa.Javascript - Funzione ricorsiva per scorrere gli elementi

La mia struttura HTML potrebbe essere qualcosa di simile

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

Ed ecco la mia funzione 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); 
} 

Tutti im ricevendo indietro è

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

Quando provo a stampare il valori di childnodes, ottengo un sacco di ritorni indefiniti.

Se qualcuno potesse spiegare cosa sto facendo male, lo apprezzerei molto.

+0

Per un primo ID duplicato non è un codice HTML valido. A parte questo, non hai effettivamente descritto cosa dovrebbe contenere esattamente l'array restituito. –

+0

@ FabrícioMatté restituirebbe una lista di valori come una stringa – dudemanbearpig

+0

"Valori" come nel loro contenuto testuale? –

risposta

8

Avrete bisogno di fare qualcosa di simile alla seguente (ricorsiva cross-browser)

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")); 

Su jsfiddle

o utilizzando 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")); 

Su jsfiddle

Senza ricorsione e cross browser sarebbe qualcosa di simile

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")); 

Su jsfiddle

+1

La tua risposta mi ha fatto impazzire. – 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

Probabilmente intendevi Tag anziché Class in 'getElementsByTagName ('*')', e 'childValues ​​[] = ...' non è una sintassi JS valida. –

+0

childValues ​​[] = ... non è una sintassi JS valida. Sì, bloccato in modalità PHP. Fisso. E no - intendevo getElementsByClassName ('*') –

+1

Sei sicuro? http://jsfiddle.net/PnEvM/ ':)' –

Problemi correlati