Как применить класс к ребенку, если все остальные дети скрыты?

Я знаю, что это очень просто с 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, вероятно, может сделать это лучше. Вы уже используете это в любом случае.

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