如何在独立card-body区块中调用JS函数更新成就完成数
问题
实现成就追踪器,点击复选框时,每个.card-body区块内的成就完成数需独立更新。当前代码仅能修改其中一个区块的数值,需调整实现区块独立计算逻辑。
原HTML代码
<div class="card-body"> <div class="heading"> <h2>Endings</h2> <p><span id="achievement-complete">0</span> / 2</p> </div> <ul> <li id="achievement_7_0"> <div class="card-content"> <input type="checkbox" id="item_7_0" class="sum" value="1" /> <label class='strikethrough' for="item_7_0"> Ending 1 </label> </div> </li> <li id="achievement_7_1"> <div class="card-content"> <input type="checkbox" id="item_7_1" class="sum" value="1" /> <label class='strikethrough' for="item_7_1"> Ending 2 </label> </div> </li> </ul> </div> <div class="card-body"> <div class="heading"> <h2>All Achievements</h2> <p><span id="achievement-complete">0</span> / 1</p> </div> <ul> <li id="achievement_8_0"> <div class="card-content"> <input type="checkbox" id="item_8_0" class="sum" value="1" /> <label class='strikethrough' for="item_8_0"> All Achievements </label> </div> </li> </ul> </div>
原JavaScript代码
var input = document.getElementsByClassName('sum'), total = document.getElementById('achievement-complete'); for (var i = 0; i < input.length; i++) { input[i].onchange = function () { var add = this.value * (this.checked ? 1 : -1); total.innerHTML = parseFloat(total.innerHTML) + add // console.log(add); } }
解决方案
1. 修复HTML的ID重复问题
DOM中ID必须唯一,原代码两个.card-body共用id="achievement-complete",导致getElementById仅能获取第一个元素。将其改为class:
<!-- 第一个区块修改 --> <p><span class="achievement-complete">0</span> / 2</p> <!-- 第二个区块修改 --> <p><span class="achievement-complete">0</span> / 1</p>
2. 修改JavaScript实现独立计算
核心逻辑:复选框状态变化时,定位其所属的.card-body容器,统计该容器内选中的复选框数量,更新对应区块的完成数。
修改后的JS代码:
// 获取所有成就复选框 const checkboxes = document.querySelectorAll('.sum'); // 为每个复选框绑定状态变更事件 checkboxes.forEach(checkbox => { checkbox.addEventListener('change', function() { // 找到当前复选框所在的.card-body父容器 const currentCard = this.closest('.card-body'); // 统计当前容器内已选中的复选框数量 const completedNum = currentCard.querySelectorAll('.sum:checked').length; // 更新当前容器的完成数显示 currentCard.querySelector('.achievement-complete').textContent = completedNum; }); });
代码说明
closest('.card-body'):从当前复选框向上查找最近的.card-body容器,确保操作范围仅局限于当前成就区块。querySelectorAll('.sum:checked').length:直接统计当前区块内已选中的复选框数量,避免手动累加可能出现的误差。- 使用
textContent替代innerHTML:更安全,适合纯文本内容的更新操作。
内容的提问来源于stack exchange,提问作者windowpi
相关产品推荐
相关产品推荐

