JS实现多层级计算树累加父节点总金额时逻辑错误如何修复
层级树金额累加功能实现方案
功能需求
使用JS开发多层级树结构的金额自动累加功能,子节点的金额向上汇总到所有上层父节点,最终得到每一层级节点的总金额。
预期效果:
原有代码
HTML结构
<div class="card-content"> <ol class="dd-list" type="1"> <li class="item">Main 1 <span class="price"> | 240,000 EGP</span></li> <ol class="dd-list"> <li class="item">Sub 1.1<span class="price"> | 130,000 EGP</span></li> <ol class="dd-list"> <li>Sub 1.3<a class="btn btn-primary shadow btn-xs sharp ml-1"><i class="fa fa-link"></i></a><span class="price"> | 130,000 EGP</span></li> <ol class="dd-list"> <li><a class="item">New Item 3</a><span class="pull-right price"> | 60,000 EGP</span></li> <li><a class="item">New Item 4</a><span class="pull-right price"> | 70,000 EGP</span></li> </ol> </ol> <li>Sub 1.2<a class="btn btn-primary shadow btn-xs sharp ml-1"><i class="fa fa-link"></i></a><span class="price"> | 110,000 EGP</span></li> <ol class="dd-list"> <li><a class="item">New Item 3</a><span class="pull-right price"> | 50000 EGP</span></li> <li><a class="item">New Item 4</a><span class="pull-right price"> | 60000 EGP</span></li> </ol> </ol> </ol> <ol class="dd-list" type="1"> <li>Main 2 <a class="btn btn-primary shadow btn-xs sharp ml-1"><i class="fa fa-link"></i></a></li> <ol class="dd-list"></ol> </ol> <ol class="dd-list" type="1"> <li>Main 3 <a class="btn btn-primary shadow btn-xs sharp ml-1"><i class="fa fa-link"></i></a></li> <ol class="dd-list"></ol> </ol> </div>
原有JS代码
$(document).ready(function(){ var sum = 0; $('ol.dd-list').each(function(){ sum = 0; $(this).find("ol > li span").each(function(i, obj){ if($(this).text() !== ""){ sum += parseFloat($(this).text()); $(this).parent().parent().prev().find('.price').text(sum); } }); sum = 0; }); });
原有代码问题
- 金额提取逻辑错误:原始金额文本包含分隔符
|、千位逗号、单位EGP,直接调用parseFloat会返回NaN,无法完成数值计算 - 遍历顺序错误:采用从上到下的遍历逻辑,计算父节点金额时子节点还未完成汇总,计算结果不符合预期
- 层级匹配不通用:固定的父子节点层级查找逻辑,无法适配任意深度的树结构
修正后实现代码
$(document).ready(function(){ // 提取金额数值的工具方法 function getPurePrice($priceEl) { if (!$priceEl.length) return 0; // 过滤所有非数字、小数点字符 let priceStr = $priceEl.text().replace(/[^0-9.]/g, ''); return priceStr ? parseFloat(priceStr) : 0; } // 倒序遍历所有层级列表,优先计算最深层子节点 $($('ol.dd-list').get().reverse()).each(function(){ const $list = $(this); // 找到当前列表对应的父级节点 const $parentItem = $list.prev('li'); if (!$parentItem.length) return; let total = 0; // 累加当前列表所有直接子节点的金额 $list.children('li').each(function(){ total += getPurePrice($(this).find('.price').first()); }); // 格式化金额后更新到父节点 const formatTotal = total.toLocaleString('en-US'); const $parentPrice = $parentItem.find('.price').first(); if ($parentPrice.length) { $parentPrice.text(` | ${formatTotal} EGP`); } else { $parentItem.append(`<span class="price"> | ${formatTotal} EGP</span>`); } }); });
实现说明
- 倒序遍历所有
dd-list,保证从最底层的叶子节点开始计算,逐层向上汇总 - 兼容不存在price元素的空父节点,自动追加金额展示元素
- 金额自动格式化千位分隔符,和原有展示格式完全统一
- 适配任意深度的层级树结构,不需要修改代码匹配层级
内容的提问来源于stack exchange,提问作者M. Sharshar
相关产品推荐
相关产品推荐

