TypeScript实现点击切换疫苗按钮颜色与文本状态
问题根因
现有代码仅在初始渲染时根据实例的vaccine属性生成对应样式的按钮,未绑定点击交互逻辑:点击后既不会修改实例的疫苗状态,也不会更新DOM显示,因此无法实现切换效果。
实现方案
采用事件委托实现点击切换,无需给每个按钮单独绑定事件,兼容排序后重绘的场景,性能更高,共3处修改:
- 给所有类的
displayInfo方法新增index入参,给疫苗按钮新增统一标识类vaccine-btn,同时绑定自定义属性data-index存储对应动物实例在数组中的下标 - 修改
cards渲染函数,遍历卡片时将数组索引传入displayInfo方法,每次渲染前先清空容器避免内容重复 - 给卡片容器绑定点击事件,通过事件委托识别疫苗按钮点击,翻转对应实例的
vaccine属性,直接更新按钮的样式和文本
注意:子类dogs和cats的displayInfo方法需要和基类做相同修改,否则子类渲染的按钮无法触发切换
关键修改代码
- 修改Animals基类的displayInfo方法,子类dogs、cats的displayInfo同步修改按钮部分即可:
// 基类displayInfo修改示例,子类同理 displayInfo(index: number) { return ` <div class="col-lg-4 col-md-6 col-sm-12 d-flex justify-content-center"> <div class="card card-decoration" style="width: 22rem;"> <img src="${this.image}" class="card-img-top" style="height:25rem; object-fit:cover"> <div class="card-title text-center bg-dark text-white p-1">${this.name}</div> <div class="card-body"> <p class="card-text"><strong>Gender:</strong> ${this.gender}</p> <p class="card-text"><strong>Age:</strong> ${this.age}</p> <p class="card-text"><strong>Size:</strong> ${this.size}</p> <!-- 新增vaccine-btn类和data-index属性 --> <h1 data-index="${index}" class="vaccine-btn text-center btn d-flex justify-content-center bg-${this.vaccine?"success":"danger"}">${this.vaccine?`Vaccinated <img src='../pics/tnailup.png' class='iconica'>`:`I need vaccine <img src='../pics/tnaildown.png' class='iconica'>`}</h1> </div> </div> </div>`; }
- 修改cards渲染函数:
function cards() { const resultContainer = document.querySelector(".result") as HTMLElement; resultContainer.innerHTML = ""; array.forEach((val, index) => { resultContainer.innerHTML += val.displayInfo(index); }); }
- 新增疫苗按钮点击逻辑,放在
cards()调用前即可,原有年龄排序逻辑无需修改:
// 事件委托处理所有疫苗按钮点击 (document.querySelector(".result") as HTMLElement).addEventListener("click", (e) => { const target = e.target as HTMLElement; // 兼容点击按钮内部图片、文字的场景,向上查找疫苗按钮元素 const vaccineBtn = target.closest(".vaccine-btn") as HTMLElement | null; if (!vaccineBtn) return; // 读取索引找到对应动物实例 const animalIndex = Number(vaccineBtn.dataset.index); const currentAnimal = array[animalIndex]; // 翻转疫苗状态 currentAnimal.vaccine = !currentAnimal.vaccine; // 更新按钮样式 vaccineBtn.classList.remove("bg-success", "bg-danger"); vaccineBtn.classList.add(currentAnimal.vaccine ? "bg-success" : "bg-danger"); // 更新按钮文本和图标 vaccineBtn.innerHTML = currentAnimal.vaccine ? `Vaccinated <img src='../pics/tnailup.png' class='iconica'>` : `I need vaccine <img src='../pics/tnaildown.png' class='iconica'>`; });
效果说明
- 初始加载时按钮状态与实例预设的
vaccine属性一致 - 点击按钮会在绿色已接种、红色待接种两种状态间循环切换,对应文本、图标同步更新
- 年龄排序后重绘的卡片无需重新绑定事件,点击功能正常
- 仅更新被点击的按钮元素,无需重绘整个卡片列表,无页面卡顿
内容的提问来源于stack exchange,提问作者andreabcsk
相关产品推荐
相关产品推荐

