Как заставить селектор nth-child пропустить скрытые divs
У меня мало случайных блоков. Всякий раз, когда блок попадает в новый ряд, я делаю его другим. Когда пользователь нажимает кнопку, я скрываю несколько блоков display:none
, и проблема возникает. Селектор nth-child
также подсчитывает скрытые элементы.
Есть ли способ игнорировать те конкретные блоки, чтобы снова каждая строка имела другой стиль? Это пример моего аналогичного сценария.
$('.hide-others').click(function () {
$('.css--all-photo').toggleClass('hidden');
})
.board-item--inner {
height:200px;
background:tomato;
text-align:center;
color:#fff;
font-size:33px;
margin-bottom:15px;
border:2px solid tomato;
}
@media (min-width:768px) and (max-width:991px) {
.board-item:nth-child(2n+1) .board-item--inner {
border:2px solid #000;
background:yellow;
color:#000;
}
}
@media (min-width:992px) and (max-width:1199px) {
.board-item:nth-child(3n+1) .board-item--inner {
border:2px solid #000;
background:yellow;
color:#000;
}
}
@media (min-width:1200px) {
.board-item:nth-child(4n+1) .board-item--inner {
border:2px solid #000;
background:yellow;
color:#000;
}
}
<link href="#" onclick="location.href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css'; return false;" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="container">
<div class="form-group">
<button class="btn btn-info hide-others" type="button">Hide others</button>
</div>
<div class="row">
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item">
<div class="board-item--inner">1</div>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item">
<div class="board-item--inner">2</div>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item css--all-photo">
<div class="board-item--inner">3</div>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item">
<div class="board-item--inner">4</div>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item">
<div class="board-item--inner">5</div>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item css--all-photo">
<div class="board-item--inner">6</div>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item">
<div class="board-item--inner">7</div>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item css--all-photo">
<div class="board-item--inner">8</div>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item">
<div class="board-item--inner">9</div>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item">
<div class="board-item--inner">0</div>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item">
<div class="board-item--inner">10</div>
</div>
</div>
<div>
Ответы
Ответ 1
Когда пользователь нажимает кнопку, я скрываю несколько блоков display:none
, и проблема возникает. Селектор nth-child
также подсчитывает скрытые элементы.
Есть ли способ игнорировать те конкретные блоки, чтобы снова каждая строка имеет другой стиль?
Проблема в том, что селектор nth-child()
смотрит на всех братьев и сестер под одним и тем же родителем, независимо от стиля. Не имеет значения, что вы применили display: none
, потому что CSS не удаляет элемент из DOM, и поэтому он все еще является родным братом.
Из спецификации:
6.6.5.2. :nth-child()
псевдо-класс
Обозначение псевдокласса :nth-child(an+b)
представляет собой элемент, который имеет + b-1 братьев и сестер, прежде чем в документе tree, для любого положительного целого или нулевого значения n и имеет родительский элемент. (акцент мой)
Чтобы правила nth-child
, которые вы объявили работать после того, как пользователь нажимает, чтобы скрыть div, вам нужно удалить скрытые div из DOM, чтобы они больше не существовали как братья и сестры.
В вашем вопросе вы запрашиваете только CSS-решение. Но в ваших комментариях вы говорите, что HTML открыт для изменений. Вы также используете немного jQuery для скрытия элементов.
С помощью одной маленькой строки кода, добавленной в ваш jQuery, проблема может быть решена:
$('.hidden').remove();
Метод .remove()
не принимает элементы (и его потомки) из DOM. В этом случае он удаляет все элементы с помощью класса hidden
.
КОРРЕКЦИЯ
Проблема с remove()
заключается в том, что элементы, взятые из DOM с помощью этого метода, не могут быть восстановлены, и это нарушает функцию переключения.
К счастью, jQuery предлагает альтернативу: detach()
.
Метод .detach()
совпадает с .remove()
, за исключением того, что .detach()
хранит все данные jQuery, связанные с удаленным элементы. Этот метод полезен, когда удаленные элементы должны быть снова вставляется в DOM позднее.
Итак, если мы заменим исходный код...
$('.hide-others').click(function () {
$('.css--all-photo').toggleClass('hidden');
})
... с этим кодом...
var divs;
$('.photos-board-item').each(function(i){
$(this).data('initial-index', i);
});
$('.hide-others').on('click', function () {
if(divs) {
$(divs).appendTo('.row').each(function(){
var oldIndex = $(this).data('initial-index');
$('.photos-board-item').eq(oldIndex).before(this);
});
divs = null;
} else {
divs = $('.css--all-photo').detach();
}
});
... сетка работает по назначению. (код кредита: @JosephMarikle)
DEMO
Теперь, независимо от того, какие divs или сколько скрыты, они могут включаться и выключаться без нарушения визуального дизайна, потому что селектор nth-child
учитывает только "видимых" братьев и сестер. Никаких изменений в CSS. Никаких изменений в HTML.
Ответ 2
Я бы сделал это с помощью комбинации селектора :nth-of-type
и небольшой модификации вашей функции переключения.
Основная идея состоит в том, чтобы не удалять те элементы .css--all-photo
из DOM, а переносить их в контейнеры <hidden>
. И unwrap()
восстановить полный набор. В этом случае :nth-of-type
сделает именно то, что вы сделали с :nth-child
.
var state = false;
$('.hide-others').click(function () {
if( !state ) {
$('.css--all-photo').wrap('<hidden>');
state = true;
} else {
$('hidden').unwrap();
state = false;
}
})
hidden { display:none; }
.board-item--inner {
height:200px;
background:tomato;
text-align:center;
color:#fff;
font-size:33px;
margin-bottom:15px;
border:2px solid tomato;
}
@media (min-width:768px) and (max-width:991px) {
div.board-item:nth-of-type(2n+1) .board-item--inner {
border:2px solid #000;
background:yellow;
color:#000;
}
}
@media (min-width:992px) and (max-width:1199px) {
div.board-item:nth-of-type(3n+1) .board-item--inner {
border:2px solid #000;
background:yellow;
color:#000;
}
}
@media (min-width:1200px) {
div.board-item:nth-of-type(4n+1) .board-item--inner {
border:2px solid #000;
background:yellow;
color:#000;
}
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="container">
<div class="form-group">
<button class="btn btn-info hide-others" type="button">Hide others</button>
</div>
<div class="row">
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item">
<div class="board-item--inner">1</div>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item">
<div class="board-item--inner">2</div>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item css--all-photo">
<div class="board-item--inner">3</div>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item">
<div class="board-item--inner">4</div>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item">
<div class="board-item--inner">5</div>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item css--all-photo">
<div class="board-item--inner">6</div>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item">
<div class="board-item--inner">7</div>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item css--all-photo">
<div class="board-item--inner">8</div>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item">
<div class="board-item--inner">9</div>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item">
<div class="board-item--inner">0</div>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item">
<div class="board-item--inner">10</div>
</div>
</div>
<div>
Ответ 3
То, что вы ищете, это nth-of-class, которого, к сожалению, не существует!
Когда вы переключаете скрытый класс с помощью JS, это единственная разница между скрытыми и показанными дочерними элементами. Поэтому вам нужно сказать css, чтобы считать divs определенного класса,
(скажем, "показано" ), но, к сожалению, селектор css nth-child не уделяет много внимания классам ребенка.
Здесь вы можете прочитать .
Ответ 4
вот пример того, что я имею в виду: https://jsfiddle.net/happy2deepak/g7gL5zfb/4/
В этом случае он будет игнорировать элементы с классом .css--all-photo
... но вы можете использовать тот класс, который вы хотите игнорировать
$('.hide-others').click(function () {
$('.user-a').not('.css--all-photo').toggleClass('hidden');
})