如何结合details标签与AJAX实现点击按需加载内容并自动折叠其他项
解决方案:结合details标签与AJAX实现按需加载+自动折叠
1. 基础HTML结构
给每个主题的details标签设置唯一标识,初始只保留标题和触发按钮,避免预加载图片:
<details class="topic-item" data-topic-id="1"> <summary> 主题1标题 <button class="load-details">Show Details</button> </summary> <!-- 预留容器,后续插入AJAX加载的内容 --> <div class="details-content"></div> </details> <details class="topic-item" data-topic-id="2"> <summary> 主题2标题 <button class="load-details">Show Details</button> </summary> <div class="details-content"></div> </details> <!-- 重复生成300个同类结构 -->
2. JavaScript核心逻辑
实现自动折叠其他项、按需加载、避免重复请求三个核心功能:
const allTopics = document.querySelectorAll('.topic-item'); allTopics.forEach(topic => { topic.addEventListener('toggle', function() { // 当前项展开时,关闭所有其他已展开的details if (this.open) { allTopics.forEach(other => { if (other !== this && other.open) other.open = false; }); const contentBox = this.querySelector('.details-content'); // 判断是否已加载过内容,避免重复请求 if (contentBox.dataset.loaded !== 'true') { const topicId = this.dataset.topicId; const loadBtn = this.querySelector('.load-details'); // 显示加载状态 loadBtn.textContent = '加载中...'; // 发起AJAX请求获取对应主题的图片内容 fetch(`/api/topic-details/${topicId}`) // 替换为你的后端接口地址 .then(res => res.text()) .then(html => { contentBox.innerHTML = html; contentBox.dataset.loaded = 'true'; loadBtn.textContent = 'Show Details'; }) .catch(() => { contentBox.innerHTML = '<p>加载失败,请重试</p>'; loadBtn.textContent = 'Show Details'; }); } } }); });
3. 后端接口返回示例
后端根据topicId返回包含三张图片的HTML片段即可:
<div class="topic-images"> <img src="/assets/topic-1-img1.jpg" alt="主题1图片1"> <img src="/assets/topic-1-img2.jpg" alt="主题1图片2"> <img src="/assets/topic-1-img3.jpg" alt="主题1图片3"> </div>
额外优化建议
- 给图片添加懒加载属性
loading="lazy",进一步减少单次加载的资源压力 - 可以给加载失败的内容添加重试按钮,提升容错性
内容的提问来源于stack exchange,提问作者levent001
相关产品推荐
相关产品推荐

