Подтвердить что ты не робот

Итерация через детей уровня N

Это похоже на что-то опрятное, которое может быть "встроено в" jQuery, но я думаю, что он все еще стоит спросить.

У меня проблема, когда это легко решить, итерации через все дочерние элементы. Недавно я обнаружил, что мне нужно учитывать случаи, когда мне нужно будет сделать уровень или два глубже, чем "1 уровень" (просто вызывающий .children() один раз), который я сейчас делаю.

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

Это то, что я делаю сейчас. Чтобы пройти второй слой в глубину, я запускаю еще один цикл после выполнения кода для каждого элемента.

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

Если я хочу пройти еще один уровень, я должен сделать это снова и снова.

Это явно не хорошо. Я бы хотел объявить переменную уровня, а потом все это позаботится. У кого-нибудь есть идеи для чистого эффективного решения jQueryish?

Спасибо!

4b9b3361

Ответ 1

Это удивительный вопрос из-за глубокого улова уровней. Проверьте скрипту.

Преобразовал это в плагин.

Активировать

$('#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);
    });
};

Ответ 2

Этот вопрос потрясающий: -)

Если вы знаете, что ваш DOM не слишком гигантский, вы можете просто найти всех потомков и отфильтровать те, которые не соответствуют:

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

После этого экземпляр jQuery "$ childrenWithinRange" будет все дочерние узлы этого родителя <div>, которые находятся на некоторой максимальной глубине. Если вы хотите точно такую ​​глубину, вы бы переключили "<" на "===". Я могу быть где-то кем-то.

Ответ 3

Вы можете просто сделать это с помощью all-selector (docs), child-selector (docs) и multiple-selector (docs) следующим образом:

Пример: http://jsfiddle.net/mDu9q/1/

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

... или если вы хотите только нацеливать детей на 3 уровня, вы можете сделать это:

Пример: http://jsfiddle.net/mDu9q/2/

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

Оба этих селектора действительны для querySelectorAll, что означает увеличение производительности в поддерживаемых браузерах.

Ответ 5

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

Убедитесь, что вы поместили свой код "do stuff" в нужное место, если вопросы, которые заказывают "материал", выполняются.