根据字符串路径生成 div 个元素

generate div elements based on string paths

我正在开发 chrome 扩展,需要根据类别生成嵌套的 DOM 元素。这些类别保存为数组中的字符串。子类别的层级通过路径显示。

这是一个简单的例子

类别数组:

let categories = [a, a/b, b, b/c/d];

我想生成这样的嵌套 div 元素:

<div id="a">
    <div id="b"></div>
</div>
<div id="b">
    <div id="c">
        <div id="d"></div>            
    </div>
</div>

以我目前的状态,我只创建了独特的顶级 div,并且不知道如何在顶级 div 中生成独特的子类别。

categories.forEach(function (i) {

  let splitedCategory = i.split('/');

  let parentID = String(splitedCategory[0]);
  let parentElement = document.getElementById(parentID);

  if(!containerElement.contains(parentElement)) {
    containerElement.innerHTML += '<div id="' + i + '"></div>';
  }
});

let categories = ['a', 'a/b', 'b', 'b/c/d'];

function f(str, html = ''){
  str = str.split('/');
  html += `<div id="${str[0]}">`
  if(str.length > 1){
    html += f(str.slice(1).join("/"));
  }
  html += `</div>`;
  return html;
}

categories.map(a=>console.log(f(a, '')))

首先您需要将数组格式化为具有级别的对象,然后递归创建 DOM 元素。这是一个完整的例子:

<html>
    <head>
        <meta charset="UTF-8" />
    </head>
    <body>
        <div id="result"></div>
        <script type="text/javascript">
        /**
         * Build HTML tree recursively from object.
         *
         * @param  Object  obj
         * @param  Element context
         * @param  String  prefix
         * @return void
         */

        function buildTree(obj, context, prefix){
            for(var key in obj){
                let div = document.createElement('div'),
                    pID = prefix ? prefix+'_'+key : key;

                div.setAttribute('id', pID);
                div.classList.add(key);
                buildTree(obj[key], div, pID);
                context.appendChild(div);
            }
        }

        /**
         * Format array as tree.
         *
         * @param  Array  arr
         * @param  String separator
         * @return Object
         */

        function arrayToTree(arr, separator){
            let formatted = {};

            if(!separator){
                separator = '/';
            }

            for(let i=0; i<arr.length; i++){
                let category = arr[i],
                    parts    = category.split(separator),
                    current  = formatted;

                for(let e=0; e<parts.length; e++){
                    let lvl = parts[e];

                    if(!current[lvl]){
                        current[lvl] = {};
                    }

                    current = current[lvl];
                }
            }

            return formatted;
        }

        var pathsTree = arrayToTree(['a', 'a/b', 'b', 'b/c/d']),
            resultDiv = document.getElementById('result');

        buildTree(pathsTree, resultDiv);
        </script>
    </body>
</html>