【问题标题】:generate html of inifnite depth menu without recursion生成无递归无限深度菜单的html
【发布时间】:2015-07-15 20:56:56
【问题描述】:

我需要从未指定数量的节点数组中为 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 则抛出异常

"最大调用栈大小"

有没有办法在 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;
    }

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

【问题讨论】:

  • 嘿!分享您的递归解决方案,以便我们可以从那里轻松构建
  • html 生成代码应该在浏览器中运行并实时生成 HTML?还是应该在服务器中生成 HTML?在哪个平台上?
  • 我更正了我的答案。整个 HTML 应该作为字符串生成并传递给 $(selector").html() 函数
  • 所以你想把递归输入放到一个非递归函数中?这有什么意义?好吧..您可以通过各种递归方式创建它..节省资源和资源密集型。
  • 您使用哪种浏览器?根据消息来源,chrome 将让您进行 10000 次以上的调用,这将成为问题2ality.com/2014/04/call-stack-size.html

标签: javascript html


【解决方案1】:

这可以解决问题(编辑:也可以缩进):

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
}

【讨论】:

  • 谢谢 :) 这是非常好的解决方案。
【解决方案2】:

构建一个队列并在其中添加您的根元素,在队列上运行一段时间并将每个子元素添加到队列中。为了将元素放置在正确的位置,你需要在 dom 中找到它们的父元素,然后将它们添加到其中。

【讨论】:

    【解决方案3】:

    为了完整起见,我也将提供我的解决方案。
    我只是想让你知道你可以通过 DOM 操作来实现这一点。

    除了我要尝试优化的一件小事之外,我非常喜欢@franciscod 的解决方案。
    如果我的猜测是正确的,我会编辑他的答案。

    尽管这可能不是最快的解决方案,但通过这种方式,您也可以立即将事件注册到每个节点。

    运行示例:http://codepen.io/GottZ/pen/jPKpaP

    这包括您对此问题的原始输入:Converting flat structure to hierarchical
    如本评论所述:generate html of inifnite depth menu without recursion

    在我看来,您不应该对每个元素都使用 id,但这取决于您自己决定。

    代码:

    var content = document.getElementById('content');
    
    var flatArray = [
        {
            Description: 'G',
            Id: 1,
            guid: 'c8e63b35',
            parent: null
        },
        {
            Description: 'Z',
            Id: 9,
            guid: 'b1113b35',
            parent: 'c8e63b35'
        },
        {
            Description: 'F',
            Id: 3,
            guid: 'd2cc2233',
            parent: 'b1113b35'
        },
        {
            Description: 'L',
            Id: 2,
            guid: 'a24a3b1a',
            parent: null
        },
        {
            Description: 'K',
            Id: 4,
            guid: 'cd3b11caa',
            parent: 'a24a3b1a'
        }
    ];
    
    var container = document.createElement('ul');
    var allNodes = {};
    
    flatArray.forEach(function (v) {
        var element = document.createElement('li');
    
        allNodes[v.guid] = {
            element: element
        };
    
        element.setAttribute('id', v.Id);
        element.setAttribute('data-guid', v.guid);
        element.appendChild(document.createTextNode(v.Description));
    
        if (!v.parent) {
            container.appendChild(element);
            return;
        }
    
        var p = allNodes[v.parent];
        if (!p.ul) {
            p.ul = p.element.appendChild(document.createElement('ul'));
        }
    
        p.ul.appendChild(element);
    });
    
    content.appendChild(container);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-26
      相关资源
      最近更新 更多