如何从二维数组创建html?

时间:2015-01-10 04:22:31

标签: javascript

我的数组有一对子元素和父元素。每个subarray的第一个元素是子元素,第二个元素是父元素

var myArray = [['activity', 'none'] , 
               ['movies', 'activity'],
               ['theater','activity'],
               ['drama', 'movies'],
               ['comedy', 'movies'],    
               ['puppet', 'theater'], 
                    . . 
               ];

我需要动态创建以下HTML:

<div id='activity'>activity

     <div id='movies'>movies
               <div id='drama'>drama</div>
               <div id='comedy'>comedy</div>  
     </div>

     <div id='theater'>
               <div id='puppet'>puppet</div>
     </div>

</div>

我试着写一个递归函数,但一切都搞砸了。我需要一个递归函数吗?

2 个答案:

答案 0 :(得分:5)

为什么不尝试一个对象而不是Element - Parent关系?

以下是vanilla JavaScript,不需要jQuery。

编辑:我保留原来的答案,但我想要一个更强大的解决方案,请查看底部的脚本。

var myObject = {
    'id' : "activity",
    'text' : "activity",
    'children' : [{
        'id' : "movies",
        'text' : "movies",
        'children' : [{
            'id' : "drama",
            'text' : "drama"
        },{
            'id' : "comedy",
            'text' : "comedy"
        }]
    },{
        'id' : "theater",
        'text' : "theater",
        'children' : [{
            'id' : "puppet",
            'text' : "puppet"
        }]
    }]
}
var generateHTML = function(data, targetEle) {
    var node = document.createElement("div");
    if (data.id)   node.setAttribute("id", data.id);
    if (data.text) node.appendChild(document.createTextNode(data.text));
    targetEle.appendChild(node);  
    if (data.children) {
        data.children.forEach(function(child, index, siblings) {
            generateHTML(child, node); // Recursion...
        }, this);
    }
}
generateHTML(myObject, document.body);
div>div {
    margin-left: 2em;
}


修改

我创建了一个脚本来将表转换为对象:

var myArray = [
    ['activity', 'none'] , 
    ['movies', 'activity'],
    ['theater','activity'],
    ['drama', 'movies'],
    ['comedy', 'movies'],    
    ['puppet', 'theater'], 
];
               
var myObject = {
    'id' : "activity",
    'text' : "activity",
    'children' : [{
        'id' : "movies",
        'text' : "movies",
        'children' : [{
            'id' : "drama",
            'text' : "drama"

        },{
            'id' : "comedy",
            'text' : "comedy"
        }]
    },{
        'id' : "theater",
        'text' : "theater",
        'children' : [{
            'id' : "puppet",
            'text' : "puppet"
        }]
    }]
};

var getById = function(id) {
    return document.getElementById(id);
};

var typeOf = function(obj) {
    return Object.prototype.toString.call(obj)
        .replace(/^\[object (.+)\]$/, "$1").toLowerCase();
}

// Converts a relatioship table to an object.
var tableToHierarchy = function(relationMatrix) {
    var generateRelationships = function(matrix) {
        var relationships = {};
        matrix.forEach(function(relationship, index, matrix) {
            var child = relationship[0];
            var parent = relationship[1];
            var children = relationships[parent] || [];
            children.push(child);
            relationships[parent] = children;
        }, this);
        return relationships;
    };
    var generateHierarchy = function(root, relationships) {
        var hierarchy = {};
        var children = relationships[root] || [];
        hierarchy.id = root;
        hierarchy.text = root;
        hierarchy.children = [];
        children.forEach(function(child, index, siblings) {
            hierarchy.children.push(generateHierarchy(child, relationships));
        });
        return hierarchy;
    };
    
    var root = relationMatrix[0][1]; // First record's parent.
    var relationships = generateRelationships(relationMatrix);
    return generateHierarchy(relationships[root], relationships);
};
    
var generateHTML = function(data, targetEle, includeLvl, idPrefix) {
    var generate = function(data, parent, level, prefix) {
        var node = document.createElement("div");
        if (data.id)    node.setAttribute("id", prefix + data.id);
        if (includeLvl) node.className = 'lvl-' + level;
        if (data.text)  node.appendChild(document.createTextNode(data.text));
        parent.appendChild(node);  
        if (data.children) {
            data.children.forEach(function(child, index, siblings) {
                generate(child, node, level+1); // Recursion...
            }, this);
        }
        return node;
    };
    switch(typeOf(data)) {
        case 'object':
            return generate(data, targetEle, 0, idPrefix);
        case 'array':
            return generate(tableToHierarchy(data), targetEle, 0, idPrefix);
    }
    return null;
};

generateHTML(myObject, getById('objTest'), true, 'obj_');
generateHTML(myArray,  getById('arrTest'), true, 'arr_');
div>div {
    margin-left: 2em;
}

.lvl-0 { color: #ff0000; }
.lvl-1 { color: #00ff00; }
.lvl-2 { color: #0000ff; }
<h2>Array</h2>
<div id="arrTest"></div>
<h2>Object</h2>
<div id="objTest"></div>

答案 1 :(得分:2)

以下代码段产生预期结果:

var myArray = [['activity', 'none'] , 
               ['movies', 'activity'],
               ['theater','activity'],
               ['drama', 'movies'],
               ['comedy', 'movies'],    
               ['puppet', 'theater'], 
               ];

var nodes = {};
for (var i in myArray) {
    var child = myArray[i][0];
    var parent = myArray[i][1];
    var children = nodes[parent] || [];
    children.push(child);
    nodes[parent] = children;
}

var divFromNode = function(parent) {
    var div = $("<div id=" + parent + ">");
    var children = nodes[parent];
    div.text(parent);
    for (i in children) {
        var child = children[i];
        div.append(divFromNode(child));
    }
    return div;
}

$("body").append(divFromNode(nodes["none"][0]));
div>div {
    margin-left: 2em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>