2011-04-22 114 views
1

我有一堆嵌套的複選框。我想選擇所有複選框,並在該集合中首先使用「最深」的元素。考慮下面的html:jQuery遍歷順序 - 深度優先

<div id="selection"></div> 
<div> 
    <label>A: <input id="a" type="checkbox" /></label><br/> 
    <div> 
     <label>B: <input id="b" type="checkbox" /></label><br/> 
     <label>C: <input id="c" type="checkbox" /></label><br/> 
    </div> 
    <label>D: <input id="d" type="checkbox" /></label><br/> 
    <label>E: <input id="e" type="checkbox" /></label><br/> 
    <div> 
     <label>F: <input id="f" type="checkbox" /></label><br/> 
     <label>G: <input id="g" type="checkbox" /></label><br/> 
     <div> 
      <label>H: <input id="h" type="checkbox" /></label><br/> 
      <label>I: <input id="i" type="checkbox" /></label><br/> 
     </div> 
    </div> 
    <label>J: <input id="j" type="checkbox" /></label><br/> 
</div> 

我使用jQuery的一些打印的選擇順序:

var x = ''; 

$('input').each(function(){ 
    x += $(this).attr('id') + ' - '; 
}); 

$('#selection').text(x.substr(0, x.length - 3)); 

結果是:a - b - c - d - e - f - g - h - i - j

我希望訂單或選定的元素爲I, H, G, F, C, B, J, E, D, AH, I, B, C, F, G, A, D, E, J。我如何重新排序選擇以與我想要的兼容?或者他們是以我想要的方式進行初始選擇的一種方式?

呃...並且爲你所有的小提琴手提供:http://jsfiddle.net/hze3M/4/!發瘋! :d

回答

4
var x = ''; 
var ar = []; 
$('input').each(function(){ 
    ar.push({length: $(this).parents().length, elmt: $(this)}); 
}); 

ar.sort(function(a,b) { 
    if (a.length - b.length > 0) { 
     return -1; 
    } 

    if (a.length - b.length < 0) { 
     return 1; 
    } 

    return 0; 
}); 

for (var i=0; i<ar.length; i++) { 
    x += (ar[i].elmt.attr("id")) + ' - '; 
};  

$('#selection').text(x); 

的jsfiddle:http://jsfiddle.net/hze3M/7/

編輯:

這裏另一種解決方案:

$.fn.sortByDepth = function() { 
    var ar = this.map(function() { 
      return {length: $(this).parents().length, elt: this} 
     }).get(), 
     result = [], 
     i = ar.length; 


    ar.sort(function(a, b) { 
     return a.length - b.length; 
    }); 

    while (i--) { 
     result.push(ar[i].elt); 
    } 
    return $(result); 
}; 


var x = $('input').sortByDepth().map(function() { 
    return this.id; 
}).get().join(' - '); 

$('#selection').text(x); 

學分這裏:Create a jQuery object collection from separate jQuery objects

+0

酷!我正在尋找一種在jQuery中加入或擴展它的方法。我想''('input')。sortByDept()。each('。 – 2011-04-22 13:54:27

+0

看看我的編輯,你有另一種實現你在找什麼 – alexl 2011-04-22 16:27:41

+0

Waaaah!Nice !!非常好的確實! – 2011-04-23 08:42:20

1
$(document).ready(function() { 
    var a = new Array(); 
    $('input').each(function(){ 
     var $this = $(this); 
     a.push({id:$this.attr('id'),level:$this.parents('div').length}); 
    }); 
    a.sort(sortByLevel); 
    /*for(var i=0; i<a.length; i++){ 
     console.log('id: '+a[i].id+'; level:'+a[i].level); 
    }*/ 
}); 

function sortByLevel(a,b){ 
    return b.level - a.level; 
} 

編輯:

$(document).ready(function() { 
    var sorted = $('input').sortByDepth(); 
    sorted.each(function(){ 
     console.log($(this).attr('id')); 
    }); 
}); 

(function($){ 
    $.fn.sortByDepth = function() { 
     return $(this).sort(function(a,b){ 
      return $(b).parents('div').length - $(a).parents('div').length; 
     }); 
    }; 
})(jQuery); 
+0

雖然它似乎毫無意義,因爲alexl打敗了我,但我花時間寫這個,所以我張貼它:) – ChrisThompson 2011-04-22 13:50:06

+0

哈哈哈......它有時會發生。他的答案使用父母()(沒有div),但我更喜歡你的分揀機。 – 2011-04-22 14:12:47

+0

用你的代碼來擴展jQuery的任何方式來獲得類似的東西?我希望能夠做'$('input')。orderInDepth()。each('。任何想法? – 2011-04-22 14:14:11

0

這裏有@阿列克謝的回答的功能jQuery的重變化(相同的基本想法):

var $sorted = $('input:checkbox').sort(function(cb1, cb2) { 
    return $(cb2).parents().length - $(cb1).parents().length(); 
}); 

這會給你安排在你想要的順序複選框一個jQuery對象。請注意,深度比較是「向後」完成的,因爲您需要首先進行深度比較。據我所知,JavaScript排序出現是穩定的,所以當深度相等時,預先存在的DOM排序自然會被保留。

編輯 —可能很明顯,但如果你想看到的 「ID」 值你只是做名單:

var idList = $sorted.map(function() { return this.id }).get().join(' - '); 
+0

也許這是一個更好的主意,編寫一個jQuery擴展函數進行排序。就像編寫一個'sortByDepth'一樣。 – 2011-04-22 14:21:47

+0

@這肯定是一種可能性,如果這是網站需要經常做的事情。 – Pointy 2011-04-22 14:27:04

0

這裏顯示了結果:I - [H - G - 的F - c - b - j - e - d - a

var x = ''; 
function getDepth(n) { 
    var i = 0; 
    while(n != document.body) { 
     n = n.parentNode; 
     i++; 
    } 
    return i; 
} 
var list = $('input'); 

list.sort(function (a, b) { 
    var a1 = getDepth(a), b1 = getDepth(b); 
    if (a1 != b1) 
     return b1 - a1; 
    else 
     return $(list).index(b) - $(list).index(a); 
}); 
$(list).each(function(){ 
    x += $(this).attr('id') + ' - '; 
}); 

$('#selection').text(x.substr(0, x.length - 3)); 

您還可以嘗試this jsFiddle file

+0

其他答案將勝過你的答案,因爲他們將是很多計算。 getDepth將被稱爲looooot的時代。 – 2011-04-22 14:20:31