0

我知道这对于 jQuery 来说非常简单,尽管我只追求 CSS 解决方案(如果可能的话)。

我有一个 div 列表,最后一项是错误消息。我有一个简单的过滤系统,如果没有一个 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。

4

2 回答 2

4

当然有可能:http: //jsfiddle.net/rudiedirkx/7b1kyfz3/3/

如果上一个项目没有隐藏,您想隐藏最后一个项目:

.listItem:not(.inactive) ~ .errorItem {
    display: none;
}

该演示使用 JS 只是为了切换inactive类,而不是用于errorItem.

不过,我仍然同意这里所有聪明人的观点:JS 可能会做得更好。反正你已经在用了。

于 2014-11-09T00:13:48.673 回答
3

您遇到的问题是您的要求:

我需要检查所有具有 listItem 类的 div 是否也具有 inactive 类,以赋予 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';
});
于 2014-11-09T00:02:30.333 回答