PHP网页可折叠的列表代码
作者:知识 来源:知识 浏览: 【大 中 小】 发布时间:2026-10-17 06:07:26 评论数:
PHP生成的折叠折叠列表,核心就一句话:用<details>和<summary>配合循环,表代比写一堆JavaScript省心太多。折叠去年我重构公司后台菜单时,表代原代码用jQuery手撸了三个折叠面板,折叠每个面板里塞了二十多行点击事件。表代后来全删了——换成PHP输出原生HTML结构,折叠代码量直接砍掉七成。表代
先看最基础的折叠写法。你只管在PHP里拼字符串:
<details> <summary>用户管理</summary> <p>这里放子菜单或者表格</p> </details> 浏览器自己会处理展开收起,表代连CSS都不用写。折叠但实际项目里,表代列表往往是折叠从数据库拉出来的。这时候循环就派上用场了。表代假设有个分类表,折叠父级和子级用parent_id关联:
$categories = [ ['id'=>1, 'name'=>'技术文档', 'parent_id'=>0], ['id'=>2, 'name'=>'PHP', 'parent_id'=>1], ['id'=>3, 'name'=>'MySQL', 'parent_id'=>1], ['id'=>4, 'name'=>'服务器', 'parent_id'=>0] ]; foreach ($categories as $cat) { if ($cat['parent_id'] === 0) { echo "<details><summary>{ $cat['name']}</summary>"; foreach ($categories as $sub) { if ($sub['parent_id'] === $cat['id']) { echo "<p>{ $sub['name']}</p>"; } } echo "</details>"; } } 这段代码直接输出嵌套结构,每个父分类都是一个可折叠块。有个坑得提醒你——如果分类层级超过两层,比如“技术文档→PHP→框架→Laravel”,那这个双层循环就抓瞎了。这时候得用递归。我一般这么写:
function renderTree($items, $parentId = 0) { $html = ''; foreach ($items as $item) { if ($item['parent_id'] === $parentId) { $children = renderTree($items, $item['id']); if ($children) { $html .= "<details><summary>{ $item['name']}</summary>{ $children}</details>"; } else { $html .= "<p>{ $item['name']}</p>"; } } } return $html; } echo renderTree($categories); 递归函数返回字符串,子级存在就包一层<details>,没有子级就输出普通段落。这样无论嵌套多深都能自动折叠。不过要注意,如果数据量上万,递归可能拖慢速度——但后台菜单几千条撑死了,完全够用。
样式上别偷懒。虽然原生<details>能工作,但默认的三角箭头太丑。我习惯把summary的默认标记去掉,换成自定义图标:
summary { list-style: none; /* 隐藏三角 */ cursor: pointer; padding: 8px; background: #f5f5f5; border-radius: 4px; } summary::-webkit-details-marker { display: none; /* Safari兼容 */ } summary::before { content: '▶ '; font-size: 12px; transition: transform 0.2s; } details[open] summary::before { transform: rotate(90deg); } 加个旋转动画,用户体验立刻不一样。还有个小技巧:默认展开某个面板,直接在<details>标签上加open属性就行。PHP里判断一下当前选中项:
$open = ($cat['id'] == $activeId) ? 'open' : ''; echo "<details { $open}>"; 最后说个坑。如果你用AJAX动态加载折叠内容,别用innerHTML往<details>里塞东西——浏览器会重新解析,导致已展开的面板全部收起。要么整块替换,要么用insertAdjacentHTML配合open属性手动维持状态。我吃过一次亏,后来干脆改成页面加载时一次性输出全部内容,反正后台数据量不大。
写这玩意儿最爽的是,不用管任何JS事件绑定。PHP输出完,浏览器自己处理交互。对于不爱写前端的人来说,这简直是救命稻草。要是你还在用老式div + onclick做折叠,赶紧换成这个,省下的时间够你多写两个接口。
