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

求助:基于ES6 Classes实现点击人物图片切换Modal动态内容

解决方案

问题分析

  1. HTML中弹窗的内容容器.members-hero被注释,导致无法获取对应的DOM元素插入内容。
  2. 点击事件仅实现了弹窗开关,未根据点击元素的data-id匹配对应成员数据,也未触发内容渲染逻辑。
  3. 原渲染方法未处理旧内容清空,会导致多次点击后内容叠加。

修改步骤及代码

1. 修复HTML结构

取消弹窗中.members-hero的注释,作为内容渲染的容器:

<!-- members popup -->
<div class="popup-members">
    <div class="members-hero">
        <div class="members-hero-photo">
            <img src="" alt="members photo">
        </div>
        <div class="members-hero-content">
            <h1 class="members-hero-name"></h1>
            <p class="members-hero-presentation"></p>
            <a href="" class="members-hero-email"></a>
        </div>
    </div>
    <button class="members-hero-btn">&larr;</button>
</div>

2. 优化JavaScript逻辑

调整类职责,让控制器统一处理事件、数据匹配和内容渲染:

const popupMembers = document.querySelector('.popup-members');
const members = document.querySelectorAll('.list-item');
const membersContainer = document.querySelector('.members-hero');
const closeMembersBtn = document.querySelector('.members-hero-btn');

// 成员数据数组
const membersList = [
  {
    id: '1',
    name: 'fulano nunes',
    img: 'img/hr1_hi_NoBG.png',
    present: 'Minim sint mollit cillum ullamco proident occaecat ex Lorem consequat ea. Deserunt eiusmod enim elit exercitation. Minim eu anim in elit consequat. Sit nisi ea sint consectetur laborum nostrud. Tempor laborum ea culpa do eu exercitation irure labore nulla excepteur dolor.',
    email: 'example@email.com'
  },
  {
    id: '2',
    name: 'fulana joaquina',
    img: 'img/hr2_hi.png',
    present: 'Minim sint mollit cillum ullamco proident occaecat ex Lorem consequat ea. Deserunt eiusmod enim elit exercitation. Minim eu anim in elit consequat. Sit nisi ea sint consectetur laborum nostrud. Tempor laborum ea culpa do eu exercitation irure labore nulla excepteur dolor.',
    email: 'example@email.com'
  },
  {
    id: '3',
    name: 'fulana abrantes',
    img: '/img/hr3_hi.png',
    present: 'Minim sint mollit cillum ullamco proident occaecat ex Lorem consequat ea. Deserunt eiusmod enim elit exercitation. Minim eu anim in elit consequat. Sit nisi ea sint consectetur laborum nostrud. Tempor laborum ea culpa do eu exercitation irure labore nulla excepteur dolor.',
    email: 'example@email.com'
  },
  {
    id: '4',
    name: 'fulana carvalho',
    img: '/img/hr4_hi.png',
    present: 'Minim sint mollit cillum ullamco proident occaecat ex Lorem consequat ea. Deserunt eiusmod enim elit exercitation. Minim eu anim in elit consequat. Sit nisi ea sint consectetur laborum nostrud. Tempor laborum ea culpa do eu exercitation irure labore nulla excepteur dolor.',
    email: 'example@email.com'
  },
  {
    id: '5',
    name: 'fulana maria',
    img: '/img/hr5_hi.png',
    present: 'Minim sint mollit cillum ullamco proident occaecat ex Lorem consequat ea. Deserunt eiusmod enim elit exercitation. Minim eu anim in elit consequat. Sit nisi ea sint consectetur laborum nostrud. Tempor laborum ea culpa do eu exercitation irure labore nulla excepteur dolor.',
    email: 'example@email.com'
  },
  {
    id: '6',
    name: 'fulana peniche',
    img: '/img/hr6_hi.png',
    present: 'Minim sint mollit cillum ullamco proident occaecat ex Lorem consequat ea. Deserunt eiusmod enim elit exercitation. Minim eu anim in elit consequat. Sit nisi ea sint consectetur laborum nostrud. Tempor laborum ea culpa do eu exercitation irure labore nulla excepteur dolor.',
    email: 'example@email.com'
  },
  {
    id: '7',
    name: 'fulana cabana',
    img: '/img/hr7_hi.png',
    present: 'Minim sint mollit cillum ullamco proident occaecat ex Lorem consequat ea. Deserunt eiusmod enim elit exercitation. Minim eu anim in elit consequat. Sit nisi ea sint consectetur laborum nostrud. Tempor laborum ea culpa do eu exercitation irure labore nulla excepteur dolor.',
    email: 'example@email.com'
  },
  {
    id: '8',
    name: 'fulano nunes',
    img: '/img/hr8_hi.png',
    present: 'Minim sint mollit cillum ullamco proident occaecat ex Lorem consequat ea. Deserunt eiusmod enim elit exercitation. Minim eu anim in elit consequat. Sit nisi ea sint consectetur laborum nostrud. Tempor laborum ea culpa do eu exercitation irure labore nulla excepteur dolor.',
    email: 'example@email.com'
  },
  {
    id: '9',
    name: 'fulano nunes',
    img: '/img/hr9_hi.png',
    present: 'Minim sint mollit cillum ullamco proident occaecat ex Lorem consequat ea. Deserunt eiusmod enim elit exercitation. Minim eu anim in elit consequat. Sit nisi ea sint consectetur laborum nostrud. Tempor laborum ea culpa do eu exercitation irure labore nulla excepteur dolor.',
    email: 'example@email.com'
  },
  {
    id: '10',
    name: 'fulana bárbara',
    img: '/img/hr10_hi.png',
    present: 'Minim sint mollit cillum ullamco proident occaecat ex Lorem consequat ea. Deserunt eiusmod enim elit exercitation. Minim eu anim in elit consequat. Sit nisi ea sint consectetur laborum nostrud. Tempor laborum ea culpa do eu exercitation irure labore nulla excepteur dolor.',
    email: 'example@email.com'
  },
  {
    id: '11',
    name: 'fulana carvalho',
    img: '/img/hr11_hi.png',
    present: 'Minim sint mollit cillum ullamco proident occaecat ex Lorem consequat ea. Deserunt eiusmod enim elit exercitation. Minim eu anim in elit consequat. Sit nisi ea sint consectetur laborum nostrud. Tempor laborum ea culpa do eu exercitation irure labore nulla excepteur dolor.',
    email: 'example@email.com'
  },
  {
    id: '12',
    name: 'fulana cabana',
    img: '/img/hr12_hi.png',
    present: 'Minim sint mollit cillum ullamco proident occaecat ex Lorem consequat ea. Deserunt eiusmod enim elit exercitation. Minim eu anim in elit consequat. Sit nisi ea sint consectetur laborum nostrud. Tempor laborum ea culpa do eu exercitation irure labore nulla excepteur dolor.',
    email: 'example@email.com'
  }
];

// 成员控制类
class MembersController {  
  constructor() {
    members.forEach(member => member.addEventListener('click', this.openModal.bind(this)));
    closeMembersBtn.addEventListener('click', this.closeModal.bind(this));
  };

  // 根据ID匹配成员数据
  getMemberById(id) {
    return membersList.find(member => member.id === id);
  }

  // 渲染成员内容到弹窗
  renderMemberContent(member) {
    membersContainer.innerHTML = `
      <div class="members-hero-photo">
          <img src="${member.img}" alt="${member.name}">
      </div>
      <div class="members-hero-content">
          <h1 class="members-hero-name">${member.name}</h1>
          <p class="members-hero-presentation">${member.present}</p>
          <a href="mailto:${member.email}" class="members-hero-email">${member.email}</a>
      </div>
    `;
  }

  // 打开弹窗并加载对应内容
  openModal(e) {
    const memberId = e.target.closest('.list-item').dataset.id;
    const targetMember = this.getMemberById(memberId);
    
    if (!targetMember) return;
    
    this.renderMemberContent(targetMember);
    
    popupMembers.style.display = 'block';
    setTimeout(() => {
      popupMembers.style.opacity = '1';
    }, 100);
  };

  // 关闭弹窗
  closeModal() {
    popupMembers.style.opacity = '0';
    setTimeout(() => {
      popupMembers.style.display = 'none';
    }, 500);
  };
};

// 初始化控制器
new MembersController();

关键修改说明

  • 恢复弹窗内容容器的DOM结构,确保能正常插入渲染内容。
  • 新增getMemberById方法,通过点击元素的data-id精准匹配成员数据。
  • renderMemberContent方法通过innerHTML直接替换容器内容,避免旧内容残留。
  • 点击事件中先匹配数据、渲染内容,再显示弹窗,逻辑连贯且符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 21:52:02