javascript – 如何为任何标题稳健地解析文档并构建仅包含这些标题的树

前端之家收集整理的这篇文章主要介绍了javascript – 如何为任何标题稳健地解析文档并构建仅包含这些标题的树前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
所以我解析了一个文档,以便用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);

猜你在找的JavaScript相关文章