如何实现含4个网格元素(各带4个子元素)的点击展开横幅
解决方案:可展开的Grid横幅布局
以下是完整的实现代码,包含Grid布局、展开/收起逻辑,以及选中状态管理:
HTML结构
<div class="banner-grid"> <div class="grid-item" data-index="1"> <button class="toggle-btn">展开项1</button> <div class="sub-items"> <div class="sub-item">子项1-1</div> <div class="sub-item">子项1-2</div> <div class="sub-item">子项1-3</div> <div class="sub-item">子项1-4</div> </div> </div> <div class="grid-item" data-index="2"> <button class="toggle-btn">展开项2</button> <div class="sub-items"> <div class="sub-item">子项2-1</div> <div class="sub-item">子项2-2</div> <div class="sub-item">子项2-3</div> <div class="sub-item">子项2-4</div> </div> </div> <div class="grid-item" data-index="3"> <button class="toggle-btn">展开项3</button> <div class="sub-items"> <div class="sub-item">子项3-1</div> <div class="sub-item">子项3-2</div> <div class="sub-item">子项3-3</div> <div class="sub-item">子项3-4</div> </div> </div> <div class="grid-item" data-index="4"> <button class="toggle-btn">展开项4</button> <div class="sub-items"> <div class="sub-item">子项4-1</div> <div class="sub-item">子项4-2</div> <div class="sub-item">子项4-3</div> <div class="sub-item">子项4-4</div> </div> </div> </div>
CSS样式
/* 主横幅Grid:4个等宽项横向排列 */ .banner-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1rem; padding: 1rem; max-width: 1200px; margin: 0 auto; } /* 单个网格项:内部用Grid布局,方便排列子元素 */ .grid-item { border: 1px solid #ddd; border-radius: 8px; padding: 1rem; display: grid; gap: 1rem; transition: all 0.3s ease; } /* 子元素容器:默认隐藏,展开后切换为Grid布局 */ .sub-items { display: none; grid-template-columns: repeat(2, 1fr); gap: 0.5rem; } /* 展开状态:显示子元素容器 */ .grid-item.expanded .sub-items { display: grid; } /* 子项基础样式 */ .sub-item { padding: 0.8rem; background-color: #f5f5f5; border-radius: 4px; text-align: center; } /* 切换按钮样式 */ .toggle-btn { padding: 0.8rem; border: none; background-color: #2196f3; color: white; border-radius: 4px; cursor: pointer; font-size: 1rem; } .toggle-btn:hover { background-color: #1976d2; }
JavaScript逻辑
允许多个项同时展开
const toggleBtns = document.querySelectorAll('.toggle-btn'); toggleBtns.forEach(btn => { btn.addEventListener('click', () => { const parentItem = btn.closest('.grid-item'); // 切换展开/收起类 parentItem.classList.toggle('expanded'); // 更新按钮文本 btn.textContent = parentItem.classList.contains('expanded') ? '收起项' : `展开项${parentItem.dataset.index}`; }); });
限制仅单个项展开(互斥模式)
如果需要点击一个项时自动收起其他项,替换上面的JS为以下代码:
const toggleBtns = document.querySelectorAll('.toggle-btn'); const gridItems = document.querySelectorAll('.grid-item'); toggleBtns.forEach(btn => { btn.addEventListener('click', () => { const parentItem = btn.closest('.grid-item'); const isCurrentlyExpanded = parentItem.classList.contains('expanded'); // 先收起所有项,重置按钮文本 gridItems.forEach(item => { item.classList.remove('expanded'); item.querySelector('.toggle-btn').textContent = `展开项${item.dataset.index}`; }); // 如果当前项原本未展开,则展开它 if (!isCurrentlyExpanded) { parentItem.classList.add('expanded'); btn.textContent = '收起项'; } }); });
关键逻辑说明
- 布局核心:主横幅用
grid-template-columns: repeat(4, 1fr)实现4个等宽横向项;每个子项容器用2列Grid排列4个子元素,保证布局整齐。 - 状态管理:通过给
grid-item添加/移除expanded类控制子元素的显示/隐藏,完全通过CSS实现状态切换,JS仅负责类操作。 - 交互逻辑:
- 允许多个展开:直接切换当前项的类即可
- 互斥展开:先清空所有展开状态,再处理当前项的状态
内容的提问来源于stack exchange,提问作者Carmazan Lilian
相关产品推荐
相关产品推荐

