JS遍历.product类元素执行函数仅首个生效问题解决
问题原因
你的代码逻辑失效核心是2个问题:
- 定义
write函数时没有设置形参接收循环传入的单个商品节点,传入的参数完全没被用到 - 函数内所有元素查找都调用全局
document.getElementById(),这个API永远只会返回整个页面中第一个匹配对应ID的元素,哪怕页面存在重复ID(重复ID本身不符合HTML规范,但你要求不能修改现有ID,不需要调整HTML结构),每次循环实际操作的都是第一个商品的元素,后续商品完全没被处理。
修复代码
只需要修改JS逻辑,将所有元素查找的范围限制在当前遍历到的商品节点内部即可,不需要改动现有HTML的ID和结构:
function write(currentProduct) { // 仅在当前商品节点范围内查找促销标识 const temPromocao = currentProduct.querySelector("#priceFrom"); // 非促销商品直接跳过 if (!temPromocao) return; // 提取价格、计算折扣,所有查找都限定在当前商品节点内 const valorDe = temPromocao.innerText.replace("R$ ", ""); const valorPor = currentProduct.querySelector("#bestPrice").innerText.replace("R$ ", ""); const valorIntDe = Number.parseFloat(valorDe.replace(",", ".")); const valorIntPor = Number.parseFloat(valorPor.replace(",", ".")); const desconto = Math.round(((valorIntDe - valorIntPor) / valorIntDe) * 100); // 找到当前商品的flag容器插入折扣标签,去掉重复的flagBox ID避免冲突 const flagArea = currentProduct.querySelector("#flagArea"); flagArea.innerHTML = `<p class="flag">-${desconto}%</p>`; } document.addEventListener("DOMContentLoaded", function() { const products = document.getElementsByClassName("product"); // 遍历所有商品节点逐个处理 for (let i = 0; i < products.length; i++) { write(products[i]); } });
补充说明
- 原来的循环用
var i会存在变量提升的闭包问题,改成let i即可避免,不影响当前逻辑但更规范 - 插入折扣标签时去掉了重复的
id="flagBox",避免和页面已有ID冲突,只保留需要的flag类即可,现有.flag-area p的样式会自动生效,不需要额外调整CSS
内容的提问来源于stack exchange,提问作者Felipe Almeida Correa
相关产品推荐
相关产品推荐

