javascript - jQuery traversing order - depth first - Stack Overflow

I have a bunch of nested checkboxes. I would like to make a selection of all checkboxes and have the &#

I have a bunch of nested checkboxes. I would like to make a selection of all checkboxes and have the 'deepest' elements first in that collection. Consider the following html:

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

I'm using some jQuery to print the selection order:

var x = '';

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

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

The result is: a - b - c - d - e - f - g - h - i - j.

I would like the order or the selected elements to be I, H, G, F, C, B, J, E, D, A or H, I, B, C, F, G, A, D, E, J. How can I reorder the selection to be patible with what I want? Or is their a way to make the initial selection the way I want?

Ow... and for all you fiddlers out there: /! Go nuts! :D

I have a bunch of nested checkboxes. I would like to make a selection of all checkboxes and have the 'deepest' elements first in that collection. Consider the following html:

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

I'm using some jQuery to print the selection order:

var x = '';

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

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

The result is: a - b - c - d - e - f - g - h - i - j.

I would like the order or the selected elements to be I, H, G, F, C, B, J, E, D, A or H, I, B, C, F, G, A, D, E, J. How can I reorder the selection to be patible with what I want? Or is their a way to make the initial selection the way I want?

Ow... and for all you fiddlers out there: http://jsfiddle/hze3M/4/! Go nuts! :D

Share Improve this question asked Apr 22, 2011 at 13:18 Kees C. BakkerKees C. Bakker 33.5k31 gold badges118 silver badges207 bronze badges
Add a ment  | 

4 Answers 4

Reset to default 6
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/hze3M/7/

EDIT:

here another solution:

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

Credits here : Create a jQuery object collection from separate jQuery objects

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

EDIT:

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

Here shows the result: 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));

You can also try this jsFiddle file.

Here's a functional jQuery-heavy variation on @alexi's answer (same basic idea):

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

That would give you a jQuery object with the checkboxes arranged in the order you want. Note that the depth parison is done "backwards" because you want the deepest ones first. The JavaScript sort appears to be stable, as far as I can tell, so when depth is equal the pre-existing DOM ordering will naturally be retained.

edit — probably obvious, but if you wanted to see the list of "id" values you'd just do:

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

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745002221a4605566.html

相关推荐

  • javascript - jQuery traversing order - depth first - Stack Overflow

    I have a bunch of nested checkboxes. I would like to make a selection of all checkboxes and have the &#

    1天前
    30

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信