从JSON递归迭代构建TreeView:代码缺失FFF、GGG节点求排查方案
问题排查与修复方案
我帮你梳理下代码里的几个关键问题,正是这些问题导致FFF和GGG节点无法渲染:
核心问题分析
递归函数的return中断了循环
在recursive函数的for循环里,你用了return recursive(n[i].Nodes, $li_child);,这意味着循环处理第一个子节点后就直接返回了,后面的节点(比如FFF所在的分支)根本没机会被遍历到。DOM元素复用导致节点被覆盖
你在循环外创建了$li_child和$span,然后在循环里反复修改它们的内容并追加,这会导致所有子节点都复用同一个DOM元素,最终只有最后一个节点能显示,而且之前的节点会被覆盖。DOM追加顺序错误
每次循环都把$ul_child追加到$li_parent,这会导致同一个ul被多次追加,而且结构混乱,正确的做法应该是先把所有子li都添加到ul中,再把这个ul一次性追加到父li里。
修复后的代码
var html = { ul: '<ul></ul>', li: '<li></li>', span: '<span></span>' }; function TreeView(jobj) { var node = jobj.data[0].Nodes[0]; var $ul_root = $(html.ul), $li_root = $(html.li); var $span = $(html.span); $span.text(node.Key); $li_root.append($span); $ul_root.append($li_root); // 处理根节点的子节点 $.each(node.Nodes, function (i, n) { var $li_parent = $(html.li); var $span = $(html.span); $span.text(n.Key); $li_parent.append($span); $li_root.append($(html.ul).append($li_parent)); recursive(n.Nodes, $li_parent); }) return $ul_root; function recursive(TreeNodes, $li_parent) { if (TreeNodes.length === 0) return; // 没有子节点直接返回 var $ul_child = $(html.ul); // 创建当前层级的ul $.each(TreeNodes, function(i, childNode) { // 为每个子节点创建新的li和span var $li_child = $(html.li); var $span = $(html.span); $span.text(childNode.Key); $li_child.append($span); $ul_child.append($li_child); // 递归处理子节点的子节点 recursive(childNode.Nodes, $li_child); }); // 把当前层级的ul追加到父li中 $li_parent.append($ul_child); } } var json = '{"data":[{"Nodes":[{"Key":"Root","Nodes":[{"Key":"AAA","Nodes":[{"Key":"BBB","Nodes":[{"Key":"CCC","Nodes":[]}]}]},{"Key":"SubRoot","Nodes":[{"Key":"DDD","Nodes":[{"Key":"EEE","Nodes":[]},{"Key":"FFF","Nodes":[{"Key":"GGG","Nodes":[]}]}]}]}]}]}'; var jobj = JSON.parse(json); // 建议用JSON.parse代替eval,更安全 $('#tree').append(TreeView(jobj));
关键修改点说明
- 移除了递归函数里的
return,改用$.each遍历所有子节点,确保每个节点都被处理 - 每次循环都创建新的
$li_child和$span,避免元素复用导致的覆盖问题 - 先构建完整的子ul(包含所有子li),再一次性追加到父li中,保证DOM结构正确
- 用
JSON.parse代替eval解析JSON,更安全可靠
这样修改后,Root和SubRoot下的所有节点(包括FFF和GGG)都能正确渲染出来了。
内容的提问来源于stack exchange,提问作者user1292656
相关产品推荐
相关产品推荐

