如何用CSS选中动态生成日期类名的各日期首个元素
按日期分组仅展示首个事件实现方案
问题背景
现有按日期升序排列的事件列表,每个事件条目内的日期节点格式为<div class="event_date_[dd-mm-yyyy格式日期]">,需要实现仅展示每个日期对应的第一个事件条目,同日期的其余条目隐藏的效果,优先使用纯CSS实现。
现有DOM结构
<div class="event"> <div class="event_date_20-06-2020">title event</div> </div> <div class="event"> <div class="event_date_20-06-2020">title event</div> </div> <div class="event"> <div class="event_date_21-06-2020">title event</div> </div> <div class="event"> <div class="event_date_22-06-2020">title event</div> </div> <div class="event"> <div class="event_date_22-06-2020">title event</div> </div>
预期效果
示例中20-06-2020对应2个事件、21-06-2020对应1个事件、22-06-2020对应2个事件,最终仅展示每个日期的第一个事件,等效于实现如下逻辑的CSS规则:
.event_date_[all-dates] {display:none;} .event_date_[first-iteration-of-a-date]:first-of-type {display:block;}
实现方案
纯CSS方案(仅适用于日期可提前枚举的场景)
CSS目前没有针对动态后缀类名自动分组选首个元素的通用能力,如果你可以提前拿到所有出现的日期值(比如服务端渲染页面时同步生成CSS),可以通过通用兄弟选择器实现效果,不需要JS介入:
/* 默认所有事件显示,可根据需求调整其他全局样式 */ .event { display: block; } /* 对每个日期,隐藏所有出现在首个该日期事件之后的同日期事件 */ .event:has(> .event_date_20-06-2020) ~ .event:has(> .event_date_20-06-2020) { display: none; } .event:has(> .event_date_21-06-2020) ~ .event:has(> .event_date_21-06-2020) { display: none; } .event:has(> .event_date_22-06-2020) ~ .event:has(> .event_date_22-06-2020) { display: none; } /* 有多少个日期就追加多少条对应规则即可 */
注意::has()选择器兼容性为Chrome 105+、Firefox 121+,如果需要兼容更旧的浏览器,建议使用JS方案。
jQuery/JS方案(通用动态场景,兼容所有场景)
如果日期是动态加载、无法提前枚举,直接用JS遍历节点做日期去重标记即可,逻辑更通用,兼容性更好:
- 先写基础CSS样式,用类控制显示状态,避免直接写行内样式:
/* 默认隐藏所有事件 */ .event { display: none; } /* 首个日期事件的显示样式,可自定义颜色等属性 */ .event.is-first-of-date { display: block; color: blue; }
- 写入jQuery逻辑,遍历节点时记录已经出现过的日期,首次出现的日期对应的事件加上标记类:
// 用集合存储已经渲染过的日期 const renderedDates = new Set(); jQuery('div[class^="event_date_"]').each(function() { // 从当前节点的类名里提取日期类 const dateClass = Array.from(this.classList).find(cls => cls.startsWith('event_date_')); if (!dateClass) return; const date = dateClass.replace('event_date_', ''); // 日期第一次出现时,给父级事件节点加显示类 if (!renderedDates.has(date)) { renderedDates.add(date); jQuery(this).closest('.event').addClass('is-first-of-date'); } });
内容的提问来源于stack exchange,提问作者nots0pro
相关产品推荐
相关产品推荐

