Поиск первого и последнего класса для группировки элементов с помощью javascript
Мое требование немного отличается от традиционного метода получения первого и последнего метода, поэтому я прошу экспертную помощь.
Я объясню с помощью примера кода
Моя структура кода
<div class="wrap">
<div class="group-a"></div>
<div class="group-a"></div>
<div class="group-a"></div>
<div class="group-a"></div>
<div class="group-b"></div>
<div class="group-b"></div>
<div class="group-b"></div>
<div class="group-a"></div>
<div class="group-a"></div>
<div class="group-a"></div>
</div>
Когда я использую метод jquery, как показано ниже
$('div.group-a:first').addClass('first');
$('div.group-a:last').addClass('last');
Результат похож на
<div class="wrap">
<div class="group-a first"></div>
<div class="group-a"></div>
<div class="group-a"></div>
<div class="group-a"></div>
<div class="group-b"></div>
<div class="group-b"></div>
<div class="group-b"></div>
<div class="group-a"></div>
<div class="group-a"></div>
<div class="group-a last"></div>
</div>
Но я хочу, чтобы результат был как ниже, с первым и последним классом для каждой группы.
<div class="wrap">
<div class="group-a first"></div>
<div class="group-a"></div>
<div class="group-a"></div>
<div class="group-a last"></div>
<div class="group-b"></div>
<div class="group-b"></div>
<div class="group-b"></div>
<div class="group-a first"></div>
<div class="group-a"></div>
<div class="group-a last"></div>
Возможно ли с помощью javascript или jquery?
Ответы
Ответ 1
Зачем перебирать классы, когда вы можете использовать смежные селекторные ролики CSS и :not
? Здесь гораздо более чистый метод!
// adding first
$(':not(.group-a) + .group-a, .group-a:first').addClass('first');
// adding last
$('.group-a:last').addClass('last');
$('.group-a + :not(.group-a)').prev().addClass('last');
Обратите внимание, что это работает для любого числа group-a
и group-b
, а для других классов, таких как group-c
, по запросу. prev()
необходим, потому что для селектора смежности CSS может быть выбран только второй элемент, а не первый. Надеюсь, это поможет!
Демо здесь
Ответ 2
Наивный способ состоял бы в итерации через каждый элемент .group-a
и проверить, является ли это либо первым потомком, либо приходит непосредственно после .group-b
, и если он либо последний ребенок, либо находится непосредственно перед .group-b
:
$('div.group-a').each(function() {
var t = $(this);
if (t.is(':first-child, div.group-b + div')) {
t.addClass('first');
}
if (t.is(':last-child') || t.next('div.group-b').length > 0) {
t.addClass('last');
}
});
Вам нужно использовать метод .next()
, чтобы проверить его следующий брат, потому что не существует селектора для сопоставления элемента, предшествующего другому.
( Вы можете использовать .prev()
вместо селектора +
, если вы хотите, чтобы ваши операторы if
были конгруэнтными.)
Адаптировать его для любого количества групп до тех пор, пока вы ищете только элементы .group-a
, просто замените .group-b
на :not(.group-a)
:
if (t.is(':first-child, div:not(.group-a) + div')) {
t.addClass('first');
}
if (t.is(':last-child') || t.next('div:not(.group-a)').length > 0) {
t.addClass('last');
}
Ответ 3
Обновление
function colorFirstLast(thisClass){
$('div').find("."+thisClass).each(function () {
var node = $(this);
var prevNode = node.prev();
var nextNode = node.next();
if (prevNode == undefined || !prevNode.hasClass(thisClass)) {
node.addClass('first');
}
if (nextNode == undefined || !nextNode.hasClass(thisClass)) {
node.addClass('last');
}
});
}
colorFirstLast('group-a');
См. рабочий код:
JSFiddle
Ответ 4
Есть ли что-то не так с обертыванием групп вместе, а затем просто с использованием первого и последнего для каждой группы?
<div class="wrap">
<div>
<div class="group-a first"></div>
<div class="group-a"></div>
<div class="group-a"></div>
<div class="group-a last"></div>
</div>
<div class="group-b"></div>
<div class="group-b"></div>
<div class="group-b"></div>
<div>
<div class="group-a first"></div>
<div class="group-a"></div>
<div class="group-a last"></div>
</div>
Ответ 5
Метод заключается в использовании метода .prev
:
$(".group-a:first").addClass("first"); // the normal one
$(".group-a:last").addClass("last"); // the normal one
$(".group-b:first").prev(".group-a").addClass("last"); // the `.group-a` which is followed by the first `.group-b`
$(".group-b + .group-a").addClass("first"); // the `.group-a` whose previous element is `.group-b`
DEMO
Ответ 6
Вы можете получить группы путем фильтрации последовательных элементов, имеющих группу классов-a
Live Demo
arr = [];
groupDivs = $('.wrap div')
groupDivs.each(function(index){
if(this.className == 'group-a')
arr.push($(this));
if(this.className != 'group-a' || index == groupDivs.length-1)
{
if(arr.length > 0)
arr[0].addClass('first');
if(arr.length > 1)
arr[arr.length-1].addClass('last');
arr.length = 0;
}
});
Ответ 7
$(".group-a:eq(0), .group-b + .group-a")
.addClass("first")
.addBack()
.find(".group-a:eq(-1), .group-a:eq(3)")
.addClass("last")
jsfiddle http://jsfiddle.net/guest271314/jF868/