2011-01-17 39 views
16

Điều này có vẻ như một cái gì đó gọn gàng mà có thể được "xây dựng vào" jQuery nhưng tôi nghĩ rằng nó vẫn còn giá trị yêu cầu.Lặp lại thông qua N cấp độ trẻ em

Tôi gặp sự cố trong đó có thể dễ dàng được giải quyết bằng cách lặp qua tất cả các phần tử con của một phần tử. Gần đây tôi đã phát hiện ra tôi cần phải tính đến các trường hợp mà tôi cần phải làm một hoặc hai cấp độ sâu hơn "mức 1" (chỉ cần gọi .children() một lần) Tôi hiện đang làm.

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

Đây là những gì tôi hiện đang làm. Để đi sâu vào lớp thứ hai, tôi chạy một vòng lặp khác sau khi thực hiện mã công cụ cho mỗi phần tử.

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

Nếu tôi muốn đi sâu thêm một mức độ khác, tôi phải làm lại tất cả.

Điều này rõ ràng là không tốt. Tôi muốn tuyên bố một biến "cấp" và sau đó có tất cả chăm sóc. Bất cứ ai có bất kỳ ý tưởng cho một giải pháp jQueryish sạch hiệu quả?

Cảm ơn!

+0

Bạn tìm kiếm gì trong elemtns? – amosrivera

+0

+1 bởi vì tôi ngạc nhiên jquery không có một bản địa chọn cho điều này, và bởi vì tôi kinda bỏ lỡ thủ công dom traversal lol. – goat

Trả lời

6

Đây là một câu hỏi tuyệt vời vì mức độ bắt sâu. Check out the fiddle.

Đã chuyển đổi plugin này thành plugin.

Kích hoạt

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

Làm cho nó chỉ lọc ra thứ thay vì là một số khách truy cập có khả năng giới hạn. Thêm jquery'ish/linh hoạt imo. – goat

+0

@chris - Tôi không thể xem cách nhận tất cả các yếu tố có vùng chứa, khi đó lọc dựa trên công cụ chọn động có thể linh hoạt hơn/hiệu quả hơn –

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

Hãy chắc chắn rằng bạn đặt "làm công cụ" mã bạn ở vị trí ngay nếu vấn đề đó ra lệnh cho "công cụ" được thực hiện trong.

+1

'--depth' sẽ không hoạt động fyi –

2

Câu hỏi này là tuyệt vời :-)

Nếu bạn có biết DOM của bạn không quá khổng lồ, bạn chỉ có thể tìm thấy tất cả các hậu duệ và lọc ra những người không đủ điều kiện:

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

Sau đó, ví dụ jQuery "$ childrenWithinRange" sẽ là tất cả các nút con của phụ huynh đó <div> nằm trong một số độ sâu tối đa. Nếu bạn muốn chính xác độ sâu đó, bạn sẽ chuyển "<" thành "===". Tôi có thể bị mất bởi một nơi nào đó.

+0

+1 Đây là cách tôi sẽ làm điều đó, trừ khi tôi cảm thấy tôi muốn lọc ra quá nhiều thứ để làm cho con cháu rất sâu. – goat

1

Bạn nên có thể chỉ cần làm điều đó với các all-selector(docs), các child-selector(docs)multiple-selector(docs) như thế này:

Ví dụ:http://jsfiddle.net/mDu9q/1/

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

...hoặc nếu bạn chỉ muốn nhắm mục tiêu trẻ em 3 cấp độ sâu, bạn có thể làm điều này:

Ví dụ:http://jsfiddle.net/mDu9q/2/

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

Cả hai bộ chọn có giá trị querySelectorAll, có nghĩa là tăng hiệu suất lớn trong các trình duyệt được hỗ trợ.

Các vấn đề liên quan