简体   繁体   English

如何在jQuery中编写一个简单的预订DOM树遍历算法?

[英]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 我想在这里找到代码: 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. 并将其转换为干净的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. 我知道递归需要argument.callee,因为jQuery中的回调是匿名的,但我对JQuery来说太新了,无法继续使用它。

Thanks! 谢谢!

As Code Duck pointed out, jQuery traverses nodes in source-order, depth-first - or, as you call it, pre-order. 正如Code Duck指出的那样,jQuery以源顺序遍历节点,深度优先 - 或者,正如您所说,预先订购。 However, contents only gets immediate children nodes, not descendants. 但是, contents只能获得直接的子节点,而不是后代。 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 另外, arguments.callee标记为弃用,因此命名(而不是匿名)函数

As a jQuery plugin: (also adds a break feature (like jQuery.each ), and an option for pre or post-order; YMMV with post-order) 作为一个jQuery插件:(还添加了一个中断功能(如jQuery.each ),以及一个前或后订单的选项; YMMV与后期订单)

$.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肯定会有一个更简单的方法来完成你想要做的任何事情......

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). jQuery有一组非常强大的选择器,它们允许您只选择并返回页面或元素中所有指定类型元素的集合(例如给定div标签中的所有段落标记)。 They'll be returned to you in the order they appear in the DOM (which is pretty much what you get with the above). 它们将按照它们在DOM中出现的顺序返回给您(这与上面提到的几乎相同)。 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. jQuery有一个内置函数来返回给定元素的子元素。

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. 然后,您可以使用$.eachcollection集上运行命令,或者如果要在集合上运行jQuery方法,则无法将其分配给变量并将方法链接到末尾。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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