开发者

Iterating Through N Level Children

开发者 https://www.devze.com 2023-02-05 17:50 出处:网络
This seems like something neat that might be \"built into\" jQuery but I think it\'s still worth asking.

This seems like something neat that might be "built into" jQuery but I think it's still worth asking.

I have a problem where that can easily be solved开发者_Go百科 by iterating through all the children of a element. I've recently discovered I need to account for the cases where I would need to do a level or two deeper than the "1 level" (just calling .children() once) I am currently doing.

jQuery.each(divToLookAt.children(), function(index, element)
    {
        //do stuff
    }
    );  

This is what I'm current doing. To go a second layer deep, I run another loop after doing stuff code for each element.

jQuery.each(divToLookAt.children(), function(index, element)
{
     //do stuff
    jQuery.each(jQuery(element).children(), function(indexLevelTwo, elementLevelTwo)
    {
        //do stuff
    }
    );  
}
);

If I want to go yet another level deep, I have to do this all over again.

This is clearly not good. I'd love to declare a "level" variable and then have it all take care of. Anyone have any ideas for a clean efficient jQueryish solution?

Thanks!


This is an awesome question because of the levels deep catch. Check out the fiddle.

Converted this to a plugin.

Activate

$('#div').goDeep(3, function(deep){ // $.fn.goDeep(levels, callback)
    // do stuff on `this`
});

Plugin

$.fn.goDeep = function(levels, func){
    var iterateChildren = function(current, levelsDeep){
        func.call(current, levelsDeep);

        if(levelsDeep > 0)
            $.each(current.children(), function(index, element){
                iterateChildren($(element), levelsDeep-1);
            });
    };

    return this.each(function(){
        iterateChildren($(this), levels);
    });
};


This question is awesome :-)

If you know your DOM is not too gigantic, you could just find all the descendants and filter out the ones that don't qualify:

var $parent = $('#parent');
var $childrenWithinRange = $parent.find('*').filter(function() {
  return $(this).parents('#parent').length < yourMaxDepth;
});

After that, the jQuery instance "$childrenWithinRange" would be all the child nodes of that parent <div> that are within some maximum depth. If you wanted exactly that depth, you'd switch "<" to "===". I may be off by one somewhere.


You should be able to just do it with the all-selector(docs), the child-selector(docs) and multiple-selector(docs) like this:

Example: http://jsfiddle.net/mDu9q/1/

$('#start > *,#start > * > *,#start > * > * > *').doSomething();

...or if you only wanted to target the children 3 levels deep, you could do this:

Example: http://jsfiddle.net/mDu9q/2/

$('#start > * > * > *').doSomething();

Both of these selectors are valid for querySelectorAll, which means big performance boost in supported browsers.


The question sounds like the answer could be XPATH. I'm not well informed about the browser-support, but in XPATH you only need to create a path like

/*/*/*/*
  • https://developer.mozilla.org/en/introduction_to_using_xpath_in_javascript (works in FF,Chrome,Safari,Opera)
  • http://msdn.microsoft.com/en-us/library/aa335968%28v=vs.71%29.aspx (didn't try it yet)


var lvlFunc = function(elmt, depth) {
    if(depth > 0) {
        elmt.children().each(function(i, e){
            // do stuff on the way down
            lvlFunc($(this), --depth);
            // do stuff on the way out
        });
        // do stuff
    }
};

lvlFunc(divToLookAt, 3);

Make sure that you put your "do stuff" code in the right location if matters which order the "stuff" is performed in.

0

精彩评论

暂无评论...
验证码 换一张
取 消