javascript - 无需递归生成无限深度菜单的html

标签 javascript html

我需要从未指定数量的节点数组中为 TreeView 创建 html。 这是一个例子

var array = [
    {
        Description: "G",
        Id: 1,
        guid: "c8e63b35",
        parent: null,
        Children: [
            {
                Description: "Z",
                Id: 9,
                guid: "b1113b35",
                parent: "c8e63b35",
                Children: [
                    {
                        Description: "F",
                        Id: 3,
                        guid: "d2cc2233",
                        parent: "b1113b35",
                    }
                ]
            }, 
        ]
    },
    {
        Description: "L",
        Id: 2,
        guid: "a24a3b1a",
        parent: null,
        Children: [
        {
            Description: "K",
            Id: 4,
            guid: "cd3b11caa",
            parent: "a24a3b1a",
        }
    }
]

结果应该是

<ul>
    <li id="1" data-guid="c8e63b35">G
        <ul>
            <li id="9" data-guid="b1113b35">Z
                <ul>
                    <li id="3" data-guid="d2cc2233">F
                    </li>
                </ul>
            </li>
        </ul>
    </li>
    <li id="2" data-guid="a24a3b1a">L
        <ul>
            <li id="4" data-guid="cd3b11caa">K
            </li>
        </ul>
    </li>
</ul>

我在这个例子中编写了正确生成 html 的递归函数,但在其他情况下它只能完美地工作到 197 深度。如果嵌套节点超过 197 则抛出异常

"The maximum call stack size"

有没有办法在 JavaScript 中不使用递归函数来做到这一点?

编辑:这是我的递归函数

    var _generateHTML = function (array, html) {
        for (var i = 0; i < array.length; i++) {
            html += "<li id=\"" + array[i].Id + "\" data-guid=\"" + array[i].guid + "\">" + array[i].Description +
                        "<ul>" + _generateHTML(array[i].Children, "") + "</ul>" +
                    "</li>";
        }
        return html;
    }

我不能使用外部库,因为这是我的工作。我之前使用递归函数创建了这棵树。我想知道这是否可能,仅此而已。

最佳答案

这样做的技巧(编辑:也缩进):

function indent (num) {
  var INDENT_SIZE = 4
  return new Array(INDENT_SIZE * num + 1).join(" ");
}


function ulli(input) {
    var CLOSE_IT = ['JUST PLEASE DO IT']
    var queue = []

    var output = ""
    var depth = 0;

    queue = queue.concat(input)
    output += "<ul>\n"
    depth++

    while (queue.length > 0) {
        var node = queue.shift()

        if (node == CLOSE_IT) {
            depth--

            output += indent(depth)
            output += "</ul></li>\n"
            continue
        }

        output += indent(depth)
        output += '<li id="' + node.Id + '" data-guid="' + node.guid + '">' + node.Description;

        if (node.Children) {
            depth++
            output += "<ul>\n"
            newQueue = [].concat(node.Children)
            newQueue.push(CLOSE_IT)
            queue = newQueue.concat(queue)
        } else {
            output += "</li>\n"
        }

    }

    output += "</ul>"

    return output
}

关于javascript - 无需递归生成无限深度菜单的html,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31424214/

相关文章:

javascript - 如何使用 JavaScript (html) 删除某个字符出现之前/之后的所有内容

html - 为什么一个 Div 的动画速度比另一个快

html - 不能 :hover whole line of a table

javascript - 让 Typescript 从普通 javascript 对象推断类型

javascript - 在浏览器 (F11) 中检测到全屏模式时使标题消失

javascript - React.js 变量

c# - 在 silverlight 和 HTML5 之间切换

html - 网络安全字体是否需要购买许可证才能在商业网站上使用?

css - 全屏背景 html5 不适用于 google chrome 浏览器

javascript - 从网站上抓取表格,使用 javascript :subOpen href link