Jquery находит набор элементов по атрибутам и помещает их в новый div

У меня есть куча <ul>с атрибутом data-year. Я хочу обернуть атрибуты data-year одним и тем же значением в div следующим образом: <div class="year"><div>

до:

<div class="projectLists">
    <ul data-year="2013">
        <li>items ...   
    </ul>
    <ul data-year="2013">
        <li>items...
    </ul>
    <ul data-year="2012">
        <li>items ...
    </ul>
    <ul data-year="2012">
        <li>items ...
    </ul>
    <ul data-year="2011">
        <li>items...
    </ul>
    <ul data-year="2011">
        <li>items...
    </ul>
</div>

после должен выглядеть так:

<div class="projectLists">
<div class="year">
    <ul data-year="2013">
        <li>items ...
    </ul>
    <ul data-year="2013">
        <li>items...
    </ul>
</div>
<div class="year">
    <ul data-year="2012">
        <li>items ...
    </ul>
    <ul data-year="2012">
        <li>items...
    </ul>
</div>
<div class="year">
    <ul data-year="2011">
        <li>items ...
    </ul>
    <ul data-year="2011">
        <li>items...
    </ul>
</div>
</div>

Я пробовал это, который оборачивает каждый ul несколько раз и не дает ожидаемых результатов:

$('.projectList ul').each(function(){
        var year = $(this).attr('data-year');
        //alert(year)
        console.log(year);

        $('.projectList ul[data-year=' + year + ']').wrapAll('<div class="year">');
        $('.projectList ul[data-year=' + year + ']').eq(0).before('<h2>'+ year +'</h2>');

});

любая помощь будет отличной, спасибо.

4 ответа

Решение

Я бы предложил:

var $ul = $('.projectLists > ul'),
    years = {};

$ul.each(function(){
   years[$(this).data('year')] = '';
});

for (year in years) {
  $ul.filter('[data-year='+ year +']').wrapAll('<div class="year"></div');
}

http://jsfiddle.net/ghvUV/

var $lists = $('.projectLists > ul'),
    years = [];

$lists.each(function() {
    var year = this.getAttribute('data-year');
    if ( ! ~$.inArray(year, years) ) {
        years.push(year);
    }
});

$.each(years, function (i, year) {
    $lists.filter('[data-year=' + year + ']').wrapAll('<div class="year">');
});

Вот скрипка: http://jsfiddle.net/CKxy8/1/

Получите массив, содержащий уникальный набор лет, итерируйте по этому массиву, для каждого года выберите все элементы ul с этим годом и оберните их в новый div.

Вы можете проверить родительский элемент при переборе, чтобы увидеть, добавили ли вы уже класс "year". Код ниже работает так, как вы ожидаете. jsFiddle

$('.projectLists ul').each(function(){
    var year = $(this).attr('data-year');

    if(!$(this).parent().hasClass("year")) {
        $(".projectLists ul[data-year='"+year+"']").wrapAll('<div class="year">');
        $(".projectLists ul[data-year='"+year+"']").eq(0).before('<h2>'+ year +'</h2>');
    }

});
Другие вопросы по тегам