JS根据数组最低值动态高亮对应proportion类div的实现问题咨询
核心问题梳理
- NodeList匹配逻辑错误:
querySelectorAll()返回的是类数组节点集合,无valueAsNumber属性,无法直接与数值比对;原数组采用push()按输入顺序存储值,与DOM节点顺序不绑定,是索引不匹配的核心诱因。 - 异常值无校验:未拦截分母为0、计算结果非有效数字的场景,无效值存入数组后会导致最小值计算错误;重复输入同一行时会重复往数组新增值,数组长度与实际出口数量错位。
修复后实现代码
JS代码
// 固定长度数组,索引0/1/2对应出口1/2/3,默认值无穷大避免未输入值被判定为最小值 const indexArray = [Infinity, Infinity, Infinity]; // 循环绑定事件,避免冗余代码 for (let i = 1; i <= 3; i++) { document.querySelector(`#outlet_actual_${i}`).addEventListener('keypress', function(e) { if (e.key === 'Enter') { const actual = document.getElementById(`outlet_actual_${i}`).valueAsNumber || 0; const design = document.getElementById(`outlet_design_${i}`).valueAsNumber || 0; // 异常值校验:设计值必须大于0,避免除以0错误 if (design <= 0) { alert('出口设计值必须大于0,请重新输入'); return; } const result = outletIndex(actual, design, i - 1); if (!isNaN(result)) { // 兼容第一个百分比节点id为percentage无后缀的情况 const percentId = i === 1 ? 'percentage' : `percentage${i}`; document.getElementById(percentId).textContent = `${result.toFixed(1)}%`; } } }) } // 接收数组索引参数,值存入对应固定位置而非push function outletIndex(a, b, arrIndex) { let result = a / b * 100; if (!isNaN(result) && isFinite(result)) { indexArray[arrIndex] = +result.toFixed(2); indexFindandHighlight(); } console.log(indexArray, result); return result; } function indexFindandHighlight(){ const proportionList = document.querySelectorAll('.proportion'); // 先清空所有节点的高亮状态 proportionList.forEach(el => { $(el).stop(true, true); el.style.backgroundColor = 'transparent'; }); const minValue = Math.min(...indexArray); // 所有值均为无效值时不高亮 if (!isFinite(minValue)) return; // 最小值索引与DOM节点索引一一对应,直接取同位置节点高亮 const minIndex = indexArray.indexOf(minValue); $(proportionList[minIndex]).effect( "highlight", {color:"#669966"}, 3000 ); }
HTML修改建议
删除所有input标签上的onkeydown="outletIndex();"属性,避免重复触发计算逻辑导致异常。
关键修复说明
- 采用固定长度数组与出口位置一一绑定,无论用户输入顺序、修改次数多少,索引永远与DOM节点顺序匹配,彻底解决索引错位问题
- 新增多层异常校验:设计值为0、计算结果非有效数字的场景直接拦截,不存入数组参与最小值计算
- NodeList索引与数组索引完全对应,无需遍历匹配数值,直接取同索引节点高亮,逻辑效率更高
内容的提问来源于stack exchange,提问作者Mark McKeon
相关产品推荐
相关产品推荐

