极具挑战:根据html <h1>信息,生成文章多级目录。期待大神

以下问题 我搞不定,看高手如何解决:

问题描述: 需要将一段html代码(主要是h1、h2、h3) 转化为对应的json

html:

    <h1>一级标题1</h1>
    <h2>二级标题1-1</h2>
    <h2>二级标题1-2</h2>
    <h1>一级标题2</h1>
    <h2>二级标题2-1</h2>
    <h3>三级标题2-1-1</h3>
    <h3>三级标题2-1-2</h3>
    <h2>二级标题2-2</h2>

希望能生成如下的json数据 ,并存储到items 变量中:

items: [
         {
             'headTitle':'一级标题1',
             'children':[
                 {'headTitle':'二级标题1-1'},
                 {'headTitle':'二级标题1-2'}
              ]
         },
         {
             'headTitle':'一级标题2',
             'children':[
                 {
                         'headTitle':'二级标题2-1',
                         'children':[
                             {'headTitle':'三级标题2-1-1'},
                             {'headTitle':'三级标题2-1-2'}
                          ]
                  },
                  {
                         'headTitle':'二级标题2-2'
                  }
             ]
         }
      ]

综上所述:根据html文档中的<h1><h2><h3>标签信息,生成多级目录。

建议考虑使用jquery 、lodsh 等辅助实现。
极具挑战,感谢大神

阅读 6.2k
5 个回答
新手上路,请多包涵

正则匹配,先把h1标签中间的东西找到。然后使用一下,那个正则的子集吧好像是。再把中间的元素整出来。

//script
    $(".main-content").find("h2,h3,h4,h5,h6").each(function(i,item){
          var tag = $(item).get(0).nodeName.toLowerCase();
          $(item).attr("id","wow"+i);
          $("#AnchorContent").append('<li><a class="new'+tag+' anchor-link" onclick="return false;" href="#" link="#wow'+i+'">'+$(this).text()+'</a></li>');
          $(".newh2").css({"margin-left":0,"font-weight":"bold"});
          $(".newh3").css({"margin-left":20,"font-size":"16px"});
          $(".newh4").css({"margin-left":40,"font-size":"14px"});
      });

  $(".anchor-link").click(function(){
      $("html,body").animate({scrollTop: $($(this).attr("link")).offset().top}, 600);
  })
//html
<div class="document-main">
    <div class="AnchorContent" id="AnchorContent">
          //js生成标题
    </div>
    <div class="main-content">
        //内容
    </div>
</div>
var items = [];
    var interimObj = null;
    var fn = {
        'H1' : function (v) {
            if(interimObj){items.push(interimObj);}
            var obj = {
                headTitle : v,
                children : []
            };
            interimObj = obj;
        },
        'H2' : function (v) {
            interimObj.children.push({
                headTitle : v,
                children : []
            });
        },
        'H3' : function (v) {
            interimObj.children[interimObj.children.length-1].children.push({
                headTitle : v
            });
        }
    };
    $('body').find('h1,h2,h3').each(function () {
        var name = $(this)[0].tagName;
        var v = $(this).html();
        fn[name](v);
    });
    items.push(interimObj);
    console.log(items);

另外一个朋友的解法:
clipboard.png

再另外一个解法:
图片描述

纯js、纯函数实现,可以方便的扩展到4、5、6级标题

var headerList = Array.from(document.querySelectorAll("h1,h2,h3"));

function tree(headerList, e){
    if(!e) return listChildren(headerList, {tagName: 'H0'})
    var resultTree = {'headTitle': e.innerText};

    if(getLevel(e) < 3){
        var children = listChildren(headerList ,e);
        if(children.length != 0)
            resultTree.children = children;
    }
    
    return resultTree;
}

function getLevel(e){
    return e.tagName.match(/\d/);
}

function listChildren(headerList, e){
    var resultList = [];
    var index = headerList.indexOf(e);

    while(headerList[index+1] && getLevel(headerList[index+1]) > getLevel(e)){
        if(getLevel(headerList[index+1]) - 1 == getLevel(e))
            resultList.push(tree(headerList, headerList[index+1]))
        index++;
    }
    return resultList;
}

//计算
console.log(tree(headerList));
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏