如何从jquery:header selector构建嵌套列表

时间:2014-05-22 21:43:40

标签: javascript jquery html css nested

我的HTML看起来像这样:

<h1 id="header1">H1</h1> <p>Lorem ipsum</p> <h2 id="header2">H2</h2> <p>lorem ipsum</p> <h2 id="header3">H2</h2> <p>lorem upsum</p> <h3 id="subHeader1">H3</h3> <p>Lorem Ipsum</p>

我正在使用以下jquery选择器来获取所有具有id的标题。

var headings = $( ":header[id]" );

我想构建一个包含所有标题的嵌套列表,以便我想出这个:

<ul><li>H1
     <ul><li>H2<li>
         <li>H2
           <ul><li>H3</li></ul>
         </li>
      </ul>
 </li></ul>

我希望有一种简单的方法来实现这一目标。搜索了stackoverflow但无法找到任何内容。我可以构建一个平面列表,但无法构建嵌套列表。

任何帮助都将非常感激。谢谢!

1 个答案:

答案 0 :(得分:2)

我想说这不是很容易。它不仅需要一些算法,还需要一些关于jQuery的知识,它是两者的组合,因此它会影响我们编码的方式。

这里的想法是你需要初始化一个根ul,在每个ul中我们应该保存对子标题集合的一些引用,然后我们需要遍历这个集合来转换每个标题为ul。新转换的ul应该添加到某个集合(某种堆栈)中,并且我们有一个while循环运行,直到该堆栈变空。

很难更好地解释它,因为正如我所说,这对于对算法和jQuery都不熟悉的新手来说尤其复杂。这是代码:

//Initialize the root UL
var ul = $('<ul>');
for(var i = 1; i < 8; i++){
  var hs = $('h' + i);
  if(hs.length){
    ul[0].childHeaders = hs
    ul[0].childHeaderLevel = i;
    break;
  }
}

var rootUl = ul;
//main loop
while(ul.length){    
  var nextUl = $();
  //loop through each ul
  ul.each(function(){
     var innerUl = this;
     var n = this.childHeaderLevel;
     //turn each childHeader into the corresponding ul
     innerUl.childHeaders.each(function(i,elem){
        var childUl = $('<ul>').append('<li>' + $(elem).html() + '</li>')
                               .appendTo(innerUl);
        childUl[0].childHeaders = $(this).nextUntil('h' + n)
                                         .filter('h' + (n+1));
        childUl[0].childHeaderLevel = n + 1;            
        nextUl = nextUl.add(childUl);
     });                            
  });
  ul = nextUl;   
}
//append the root UL to the body after emptying
$('body').empty().append(rootUl);

Demo.