在javascript中遍历树

时间:2013-04-10 05:16:50

标签: javascript

我有一个如下所示的javascript变量:

 var treeNode= [{"id":"T1"},{"id":"T2","children":[{"id":"T3"},{"id":"T4"},{"id":"T5","children":[{"id":"T6"}, {"id":"T7"},{"id":"T8"}]},{"id":"T9"},{"id":"T10"}]},{"id":"T11"},{"id":"T12"}];

节点t3,t4,t5,t6,t7,t8,t9,t10是节点t2的子节点  我在每个节点上都有一个停用链接。点击停用链接激活并删除链接。图片中提到。 enter image description here

现在我想在父节点的所有子节点上进行相同的活动和删除链接。 例如T3,T4,T5,T6,T7,T8,T9,T10是T2的孩子。 如果我点击T5,那么这将适用于T6,T7,T8。

我尝试了下面的递归代码。可能是我的方法不对。请给我建议。

var objTreeNode = eval(treeNode);
trav(objTreeNode); 
function trav(TreeNodeObj){
    var i=0;
    for (i=0;i<TreeNodeObj.length;i++){

        if(!TreeNodeObj[i].children){
            if(objID==TreeNodeObj[i].id){ // will get T2 if click on deactivate link of Item T2
            document.getElementById('span_'+TreeNodeObj[i].id).innerHTML = '<a href="javascript:activate(\'' + objID + '\');">Activate</a>    <a href="javascript:deleteNode(\'' + objID
            +'\');">Delete</a>';
            }
        }
        else{
            childObj = TreeNodeObj[i].children;
            trav(childObj)
        }
    }

}

1 个答案:

答案 0 :(得分:0)

您的代码中有一些愚蠢的东西,让我修复它们:

<强> 1。 “Eval是邪恶的!”

var treeNode= [{"id":"T1"},{"id":"T2","children":[{"id":"T3"}]}];
var objTreeNode = eval(treeNode);
trav(objTreeNode);

为什么要调用eval()? 让我们看看MDN对此有何看法:

  • Don't use eval!这是危险而缓慢的。 There are safe (and fast!) alternatives to eval() for common use-cases.

    那么你的“用例”是什么?你为什么在这里打电子邮件?什么是“更好”的解决方案?如果您阅读MDN上的整个文档,您可以阅读:

  • If the argument of eval() is not a string, eval() returns the argument unchanged.

    因此,除非treeNode是字符串var objTreeNode = eval(treeNode);,否则基本上等于var objTreeNode = treeNode;

您可以删除整个eval()行,只使用treeNode。它已经是一个对象。

<强> 2。驼峰

function trav(TreeNodeObj) {

这不仅仅是一个错误:在JavaScript中(以及大多数使用类似C语法的语言),函数的参数都是用lower camel case编写的(第一个字母是小写的,每个其他单词都是第一个字母是大写的。)

function trav(treeNodeObj) {

第3。 objID未定义

您的代码中没有定义objID变量。虽然您可能在给定时间在其他位置定义了全局,但将它作为函数中的参数引入会更安全。

function trav(treeNodeObj, objID) {

<强> 4。您的代码对什么以及何时做什么

让我弄清楚你的代码目前在做什么:

  • 迭代给定对象的子属性(希望是一个数组)。
    • 如果元素没有子元素
      • 检查数组项是否具有所需的ID属性,并将其更改为innerHTML
    • 否则
      • 调用孩子的功能

它的作用:如果元素没有子元素,则使用给定的ID更改元素。

您需要的是:更改具有给定ID的元素以及它的子元素。

我刚修改了你的功能:

function trav(treeNodeObj, objID, activate) {
    var i = 0;
    for (i = 0; i < treeNodeObj.length; i++) {
        var childrenActive = false;

        if (objID === treeNodeObj[i].id || activate) { // will get T2 if click on deactivate link of Item T2
            childrenActive = true;
            document.getElementById('span_' + treeNodeObj[i].id).innerHTML = '<a href="javascript:activate(\'' + objID + '\');">Activate</a>    <a href="javascript:deleteNode(\'' + objID + '\');">Delete</a>';
        }

        if (treeNodeObj[i].children) {
            childObj = treeNodeObj[i].children;
            trav(childObj, objID, childrenActive);
        }
    }
}

因为您需要更改我需要引入剪切的所有子元素。这是activate参数。如果activate参数为true,则不再需要检查ID,因为您知道我们正在迭代具有给定ID的元素的子元素,因此无论如何都要更改元素。

即使他们有子节点,你也需要更改元素,所以我重新组织了if-s。

我也为你做了一个jsfiddle测试:http://jsfiddle.net/JZ52g/3/

您可以在函数调用中更改id参数。