我知道这对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
类。因此,我需要检查所有类为listItem
的div是否也具有inactive
的类,以使errorItem
类具有display:block
的样式。
仅供参考,我正在为我的列表和过滤系统使用Wookmark插件。我也在用更少的。
当然有可能:http://jsfiddle.net/rudiedirkx/7b1kyfz3/3/
如果前一个项目没有隐藏,您想隐藏最后一个项目:
.listItem:not(.inactive) ~ .errorItem {
display: none;
}
这个演示使用JS只是切换inactive
类,而不是errorItem
的显示逻辑。
不过,我仍然同意这里所有聪明人的观点:JS可能会做得更好。无论如何,你已经在使用它了。
您的问题在于您的需求:
我需要检查是否所有具有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';
});