8

I've just started reading up on JavaScript and I'm trying to write a small recursive function that would search through given nodes and return a list of values as a string.

My HTML structure could be something like

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

And Here is my Javascript function:

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

All im getting back is

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

When I try to print the childnodes values, I get a bunch of undefined returns.

If anybody could explain what I'm doing wrong, I'd really appreciate it.

dudemanbearpig
  • 1,264
  • 3
  • 12
  • 19

2 Answers2

11

You will need to do something like the following (recursive 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"));

On jsfiddle

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

On jsfiddle

Without recursion and cross browser would be something like this

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

On jsfiddle

Xotic750
  • 22,914
  • 8
  • 57
  • 79
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);
  }
}
Shylo Hana
  • 1,792
  • 13
  • 10
  • You probably meant Tag instead of Class in `getElementsByTagName('*')`, and `childValues[] = ...` is not valid JS syntax. – Fabrício Matté Aug 01 '13 at 21:16
  • childValues[] = ... is not valid JS syntax. Yeah - stuck in PHP mode. Fixed. And no - I meant getElementsByClassName('*') – Shylo Hana Aug 01 '13 at 22:37
  • Sure am. I've been using it for a couple of functions on my local machine. Nothing live to show, unfortunately. – Shylo Hana Aug 04 '13 at 20:43