views:

417

answers:

3

I'd like to take the code found here: http://www.jslab.dk/articles/non.recursive.preorder.traversal.part2

// HTML element
var root = document.documentElement;

recursivePreorder(root);

// Recusively find and handle all text nodes
function recursivePreorder(node) {  
  // If node is a text node
  if (node.type == 3) {
    // Do something with node
  }
  // else recurse for each child node
  else {
    for(var i=0; i<node.childNodes.length; i++)
      recursivePreorder(node.childNodes[i]);
  }
}

and convert it into clean jQuery.

Any idea? I know recursion requires argument.callee since the callbacks in jQuery are anonymous, but I'm too new to JQuery to take it any further.

Thanks!

A: 

I think it's as simple as

var collection=$(document).contents().filter(function() { return this.nodeType == 3; });

Then, you're could either run your commands on the collection set using $.each, or if you want to run a jQuery method on the set, you could not assign it to a variable and chain the method onto the end.

Alex JL
But will that navigate the tree in a Preorder algorithm?
beriberikix
I don't know what 'preorder' means, actually. On the site you linked it says 'preorder traversal is a ordering of the elements as they are ordered in the source code.' I would assume it does, as that's the most natural way to do it, but sorry, I don't know that detail about jQuery's implementation.
Alex JL
http://en.wikipedia.org/wiki/Tree_traversal
beriberikix
A: 

Unless this is a homework assignment and you're forced to go through all the loopy madness, there's surely an easier way with jQuery to accomplish whatever you're trying to do...

jQuery has a pretty robust set of selectors that will allow you to just select and return a collection of all of a specified type of element within a page or element (ex. all of the paragraph tags in a given div tag). They'll be returned to you in the order they appear in the DOM (which is pretty much what you get with the above). Alternatively, you can use a filter like suggested above.

If you need to do this in some specific order, then I would suggest using selectors or filters to grab the element you want to start at and then loop through its children recursively. jQuery has a built in function to return the children of a given element.

Brandon Black
+2  A: 

As Code Duck pointed out, jQuery traverses nodes in source-order, depth-first - or, as you call it, pre-order. However, contents only gets immediate children nodes, not descendants. Try this:

$(document).contents ().each (function processNodes ()
{
    if (this.nodeType == 3)
        doSomething (this); // do something with text node
    else
        $(this).contents ().each (processNodes);
});

As an aside, arguments.callee is marked for deprecation, hence the named (as opposed to anonymous) function

K Prime