You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现点击DIV时从JSON加载项目About内容到右侧滑出面板?

如何实现点击触发右侧滑出的项目详情面板

已通过JSON成功加载项目图片并实现轮播,但无法实现点击ABOUT区域时从右侧滑出包含项目Title和About内容的独立面板,需求是点击后滑出面板展示当前项目的标题和描述,点击可收起。

尝试过的无效HTML代码

<div id="open-right-panel-1" class="about-title cursor-pointer" style="z-index: 10000000;">
    <div id="pantonier-1">
        <div class="descriptionSide">
            <div class="title" style="color: white;">Description</div>
        </div>
    </div>
    <div class="description hidden-about">
        <u>Project Name</u><br>
        <div style="margin-left: 7%;">
            <p>Project description</p>
        </div>
    </div>
</div>

当前核心代码

页面结构HTML

<nav class="nav-wrapper row horizontalList">
    <!-- PROJECT LIST FROM JSON DATA -->
    <ul id="project-list" class="cursor-pointer"></ul>
</nav>
<section class="content-wrapper">
    <div class="gallery-wrapper slideshow-container">
        <div>
            <img id="gallery" src="./assets/img/p1_img_1.jpg" alt="Gallery picture" />
            <!-- 注释掉的描述面板 -->
        </div>
        <div>
            <img id="gallery" src="./assets/img/p2_img_1.jpg" alt="Gallery picture" />
        </div>
        <div>
            <img id="gallery" src="./assets/img/p3_img_1.jpg" alt="Gallery picture" />
        </div>
        <div>
            <img id="gallery" src="./assets/img/p4_img_1.jpg" alt="Gallery picture" />
        </div>
        <div>
            <img id="gallery" src="./assets/img/p5_img_1.jpg" alt="Gallery picture" />
        </div>
    </div>
    <div class="hidden buttonLeft" aria-label="Previous" onclick="plusSlides(-1)"></div>
    <div class="hidden buttonLeft" aria-label="Next" onclick="plusSlides(1)"></div>
</section>

填充逻辑JavaScript

$(document).ready(function () {
 populateMenuList();
 setProject(data.Projects[0])
 $(".about-title").on("click", () => toggleAboutOverlay())
});

function populateMenuList() {
   data.Projects.forEach(i => {
       var listElement = $(`<li class="list-item">${i.Title}</li>`)
       listElement.on("click", () => {setProject(i)})
       $("#project-list").append(listElement)
   });
}

var isSlicked = false

function setProject(project) {
   // Stop Slick to avoid bugs
   if(isSlicked) {
       $(".gallery-wrapper").slick("unslick")
       $(".gallery-wrapper").empty()
   }
   // Set images in slick gallery (dont forget to add alt text)
   project.Images.forEach(i => { 
       $(".gallery-wrapper").append(`<div><img src="./assets/img/${i.FileName}" alt="${i.AltText}"></div>`)
   })
   // Restart Slick
   isSlicked = true
   $(".gallery-wrapper").slick({
       autoplay: false,
       autoplaySpeed: 2000,
       arrows: true,
       adaptiveHeight: true,
   });
}

项目数据JSON

{
  "Projects": [
    {
      "Title": "Project_1",
      "About": "Description",
      "Images": [
        {
          "FileName": "p1_img_1.jpg",
          "AltText": "Première image du projet"
        },
        {
          "FileName": "p1_img_2.jpg",
          "AltText": "Première image du projet"
        },
        {
          "FileName": "p1_img_3.jpg",
          "AltText": "Première image du projet"
        },
        {
          "FileName": "p1_img_4.jpg",
          "AltText": "Première image du projet"
        },
        {
          "FileName": "p1_img_5.jpg",
          "AltText": "Première image du projet"
        },
        {
          "FileName": "p1_img_6.jpg",
          "AltText": "Première image du projet"
        },
        {
          "FileName": "p1_img_7.jpg",
          "AltText": "Première image du projet"
        },
        {
          "FileName": "p1_img_8.jpg",
          "AltText": "Première image du projet"
        }
      ]
    },
    {
      "Title": "Project_2",
      "About": "My project description",
      "Images": [
        {
          "FileName": "p2_img_1.jpg",
          "AltText": "Première image du projet"
        },
        {
          "FileName": "p2_img_2.jpg",
          "AltText": "Première image du projet"
        },
        {
          "FileName": "p2_img_3.jpg",
          "AltText": "Première image du projet"
        },
        {
          "FileName": "p2_img_4.jpg",
          "AltText": "Première image du projet"
        },
        {
          "FileName": "p2_img_5.jpg",
          "AltText": "Première image du projet"
        },
        {
          "FileName": "p2_img_6.jpg",
          "AltText": "Première image du projet"
        },
        {
          "FileName": "p2_img_7.jpg",
          "AltText": "Première image du projet"
        },
        {
          "FileName": "p2_img_8.jpg",
          "AltText": "Première image du projet"
        },
        {
          "FileName": "p2_img_9.jpg",
          "AltText": "Première image du projet"
        },
        {
          "FileName": "p2_img_9.jpg",
          "AltText": "Première image du projet"
        }
      ]
    }
  ]
}

解决方案

1. 调整面板HTML结构

把详情面板放在轮播容器外面,避免轮播重建时被清空:

<section class="content-wrapper">
    <!-- 轮播容器保持不变 -->
    <div class="gallery-wrapper slideshow-container">...</div>
    <!-- 添加右侧滑出面板 -->
    <div class="about-panel-container">
        <div class="about-title cursor-pointer">
            <div class="descriptionSide">
                <div class="title" style="color: white;">Description</div>
            </div>
        </div>
        <div class="about-panel hidden-about">
            <h3 class="panel-title"></h3>
            <div class="panel-about"></div>
        </div>
    </div>
    <!-- 轮播按钮保持不变 -->
    <div class="hidden buttonLeft" aria-label="Previous" onclick="plusSlides(-1)"></div>
    <div class="hidden buttonLeft" aria-label="Next" onclick="plusSlides(1)"></div>
</section>

2. 添加CSS实现滑出动画

/* 面板容器固定在右侧 */
.about-panel-container {
    position: fixed;
    top: 0;
    right: 0;
    height: 100vh;
    z-index: 1000;
}

/* 触发按钮样式 */
.about-title {
    padding: 1rem;
    background: #000;
    cursor: pointer;
    transition: all 0.3s ease;
}

/* 滑出面板样式 */
.about-panel {
    position: absolute;
    top: 0;
    right: 0;
    width: 300px;
    height: 100vh;
    background: #fff;
    padding: 2rem;
    transform: translateX(100%);
    transition: transform 0.3s ease;
    box-shadow: -2px 0 5px rgba(0,0,0,0.2);
}

/* 显示面板的类 */
.about-panel.active {
    transform: translateX(0);
}

/* 初始隐藏类 */
.hidden-about {
    transform: translateX(100%);
}

3. 修改JavaScript逻辑

  • 更新setProject函数,同步更新面板内容
  • 用事件委托绑定点击事件,避免动态元素失效
  • 实现面板切换函数
$(document).ready(function () {
 populateMenuList();
 setProject(data.Projects[0]);
 // 事件委托绑定点击,确保切换项目后事件依然生效
 $(document).on("click", ".about-title", toggleAboutOverlay);
});

function populateMenuList() {
   data.Projects.forEach(i => {
       var listElement = $(`<li class="list-item">${i.Title}</li>`);
       listElement.on("click", () => setProject(i));
       $("#project-list").append(listElement);
   });
}

var isSlicked = false;
// 存储当前选中项目
let currentProject = null;

function setProject(project) {
   currentProject = project;
   // 同步更新面板内容
   $(".panel-title").text(project.Title);
   $(".panel-about").text(project.About);

   // 原有轮播逻辑保持不变
   if(isSlicked) {
       $(".gallery-wrapper").slick("unslick");
       $(".gallery-wrapper").empty();
   }
   project.Images.forEach(i => { 
       $(".gallery-wrapper").append(`<div><img src="./assets/img/${i.FileName}" alt="${i.AltText}"></div>`);
   });
   isSlicked = true;
   $(".gallery-wrapper").slick({
       autoplay: false,
       autoplaySpeed: 2000,
       arrows: true,
       adaptiveHeight: true,
   });
}

// 切换面板显示/隐藏
function toggleAboutOverlay() {
    $(".about-panel").toggleClass("active");
}

关键说明

  • 面板脱离轮播容器:避免轮播重建时被empty()清空
  • 事件委托:解决动态元素点击事件失效问题
  • CSS transform动画:实现平滑滑出效果,比display切换更流畅
  • 实时同步数据:切换项目时立即更新面板内容,保证展示当前项目信息

内容的提问来源于stack exchange,提问作者ambaamba

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 23:25:18