Как применить класс к ребенку, если все остальные дети скрыты?
Я знаю, что это очень просто с jQuery, хотя я только после решения CSS (если это возможно).
У меня есть список делений, с последним элементом сообщения об ошибке. У меня есть простая система фильтрации, и если ни один из div-ов не соответствует выбранному фильтру, я бы хотел отобразить div-ошибку.
Структура HTML:
<div id="listHolder">
<div class="listItem" data-filter-class="["filter1"]"></div>
<div class="listItem" data-filter-class="["filter2"]"></div>
<div class="listItem" data-filter-class="["filter1"]"></div>
<div class="listItem" data-filter-class="["filter4"]"></div>
<div class="errorItem">Nothing to display here</div>
</div>
Чего я пытаюсь достичь:
Если div не соответствует ни одному из фильтров, мой плагин фильтра дает им класс inactive
, Следовательно, мне нужно проверить, все ли div с классом listItem
также есть класс inactive
дать errorItem
класс стиль display:block
,
К вашему сведению, я использую плагин Wookmark для своего списка и системы фильтрации. Я также использую LESS.
2 ответа
Проблема у вас в вашем требовании:
Мне нужно проверить, все ли div с классом listItem также имеют класс неактивный, чтобы дать классу errorItem стиль
display:block
Хотя мы можем установить стиль для финала <div>
элемент, основанный на его предыдущих братьях и сестрах, мы не можем (не зная, сколько их может быть), 'проверить, все ли div' имеют inactive
учебный класс. Мы можем, однако, использовать братский комбинатор (+
) и громоздкий селектор:
.errorItem {
display: none;
}
.listItem.inactive + .listItem.inactive + .listItem.inactive + .listItem.inactive + errorItem {
display: block;
}
Это, однако, смешно (особенно если перед динамическим числом элементов .errorItem
элемент.
Если есть имя класса, примененное к элементу, который соответствует поставленным фильтрам, active
например, это намного проще и достигается:
.errorItem {
display: block;
}
.listItem.active ~ .errorItem {
display: none;
}
Кроме того, как указано в комментариях, оператор отрицания также доступен (хотя, очевидно, это зависит от реализации используемым браузером), что поддается селектору:
.errorItem {
display: block;
}
.listItem:not(.inactive) ~ .errorItem {
display: none;
}
В целом, я настоятельно рекомендую использовать JavaScript для поддержки этой функциональности, тем более что использование Wookmark подразумевает использование JavaScript (если не обязательно jQuery) уже на том же сайте.
Родной JavaScript:
function hasPrecedingSibling (elem, state) {
if (!state) {
return false;
}
var found = false,
cur = elem;
while (cur.previousElementSibling && found === false) {
if (cur.classList.contains(state)) {
found = true;
}
else {
cur = cur.previousElementSibling;
}
}
return found;
}
[].forEach.call(document.querySelectorAll('.errorItem'), function (err) {
err.style.display = hasPrecedingSibling (err, 'active') ? 'none' : 'block';
});
Конечно, это возможно: http://jsfiddle.net/rudiedirkx/7b1kyfz3/3/
Вы хотите скрыть последний элемент, если предыдущий элемент не скрыт:
.listItem:not(.inactive) ~ .errorItem {
display: none;
}
Демонстрация использует JS только для переключения inactive
класс, не для отображения логики errorItem
,
Я все еще согласен со всеми умными людьми здесь: JS, вероятно, может сделать это лучше. Вы уже используете это в любом случае.