所以我解析了一个文档,以便用stackHeadings()获取所有标题.我这样做是为了使用buildNav()构建Microsoft Word样式文档映射.这目前工作正常,但它不是非常强大,并且随着标题不遵循严格的顺序而中断……例如(如果你从一个H2开始它就会断开,如果你将H3嵌套在下面,H1则它会断开,等等……)
我无法找到解决这个问题的最佳方法(使其更加强大).我正在利用jQuery的`nextUntil’函数来查找两个h1之间的所有h2.
一种可能性是取代:
elem.nextUntil( 'h' + cur,'h' + next )
同
elem.nextUntil( 'h' + cur,'h' + next + ',h' + (next + 1) + ',h' + (next + 2) ... )
找到同一级别的两个标题之间的所有子标题.但现在h3的h3子女只会嵌套一级而不是两级.
那么你必须将当前的标题级别与父标题级别进行比较,如果跳转多于一个(h1 – > h3),则必须在它们之间创建一个空子项作为嵌套占位符为了缺少h2.
任何想法或解决方案将不胜感激!
stackHeadings = (items,cur,counter) -> cur = 1 if cur == undefined counter ?= 1 next = cur + 1 for elem,index in items elem = $(elem) children = filterHeadlines( elem.nextUntil( 'h' + cur,'h' + next ) ) d.children = stackHeadings( children,next,counter ) if children.length > 0 d filterHeadlines = ( $hs ) -> _.filter( $hs,( h ) -> $(h).text().match(/[^\s]/) ) buildNav = ( ul,items ) -> for child,index in items li = $( "<li>" ) $( ul ).append( li ) $a = $("<a/>") $a.attr( "id","nav-title-" + child.id ) li.append( $a ) if child.children subUl = document.createElement( 'ul' ) li.append( subUl ) buildNav( subUl,child.children ) items = stackHeadings( filterHeadlines( source.find( 'h1' ) ) ) ul = $('<ul>') buildNav( ul,items)
解决方法
我把一些能做你想要的事情的JavaScript组合在一起
http://jsfiddle.net/fA4EW/
这是一个相当简单的递归函数,它使用一系列元素(节点)并相应地构建UL结构.为了与问题保持一致,当你从H1到H3等时,我添加了占位符(空)列表元素.
function buildRec(nodes,elm,lv) { var node; // filter do { node = nodes.shift(); } while(node && !(/^h[123456]$/i.test(node.tagName))); // process the next node if(node) { var ul,li,cnt; var curLv = parseInt(node.tagName.substring(1)); if(curLv == lv) { // same level append an il cnt = 0; } else if(curLv < lv) { // walk up then append il cnt = 0; do { elm = elm.parentNode.parentNode; cnt--; } while(cnt > (curLv - lv)); } else if(curLv > lv) { // create children then append il cnt = 0; do { li = elm.lastChild; if(li == null) li = elm.appendChild(document.createElement("li")); elm = li.appendChild(document.createElement("ul")); cnt++; } while(cnt < (curLv - lv)); } li = elm.appendChild(document.createElement("li")); // replace the next line with archor tags or whatever you want li.innerHTML = node.innerHTML; // recursive call buildRec(nodes,lv + cnt); } } // example usage var all = document.getElementById("content").getElementsByTagName("*"); var nodes = []; for(var i = all.length; i--; nodes.unshift(all[i])); var result = document.createElement("ul"); buildRec(nodes,result,1); document.getElementById("outp").appendChild(result);