简体   繁体   中英

How to write a simple preorder DOM tree traversal algorithm in jQuery?

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!

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

As a jQuery plugin: (also adds a break feature (like jQuery.each ), and an option for pre or post-order; YMMV with post-order)

$.fn.walk = function(visit, post_order) {
    if(this.length === 0) { return; }
    this.each(function(i) {
        if (!post_order) {
            if (visit.call(this, i, this) === false) { return false; }
        }
        $j(this).children().walk(visit, post_order);
        if (post_order) { return visit.call(this, i, this); }
    });
}

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM