Порядок обхода jQuery - сначала глубина - PullRequest
2 голосов
/ 22 апреля 2011

У меня есть куча вложенных флажков. Я хотел бы сделать выбор всех флажков и иметь «самые глубокие» элементы первыми в этой коллекции. Рассмотрим следующий 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>

Я использую 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, A или H, I, B, C, F, G, A, D, E, J. Как я могу изменить порядок выбора, чтобы он был совместим с тем, что я хочу? Или это способ сделать первоначальный выбор так, как я хочу?

Ой ... и для всех вас, скрипачей: http://jsfiddle.net/hze3M/4/! Сходите с ума! : D

Ответы [ 4 ]

5 голосов
/ 22 апреля 2011
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/

EDIT:

здесь другое решение:

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

Кредиты здесь: Создание коллекции объектов jQuery из отдельных объектов jQuery

1 голос
/ 22 апреля 2011
$(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 голосов
/ 22 апреля 2011

Здесь показан результат: 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));

Вы также можете попробовать этот файл jsFiddle .

0 голосов
/ 22 апреля 2011

Вот функциональный вариант jQuery-ответа @ alexi (та же основная идея):

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

Это даст вам объект jQuery с флажками, расположенными в нужном вам порядке. Обратите внимание, что сравнение глубины выполняется «назад», потому что вы хотите сначала самые глубокие. Насколько я могу судить, сортировка JavaScript выглядит стабильной, поэтому, когда глубина равна, существующий порядок DOM будет естественным образом сохранен.

edit & mdash; вероятно, очевидно, но если вы хотите увидеть список значений «id», вы просто сделаете:

var idList = $sorted.map(function() { return this.id }).get().join(' - ');
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...