Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/369.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 递归JS函数列出Hx HTML标记?_Javascript_Jquery_Html_Recursion - Fatal编程技术网

Javascript 递归JS函数列出Hx HTML标记?

Javascript 递归JS函数列出Hx HTML标记?,javascript,jquery,html,recursion,Javascript,Jquery,Html,Recursion,我有一些代码: $('section').each(function() { var the_id; var list_item; $(this).find('h2').each(function() { the_id = $(this).attr('id'); $('nav > ol').append('<li><a href="#' + the_id + '">' + $(this).text() + '&

我有一些代码:

$('section').each(function() {
    var the_id;
    var list_item;
    $(this).find('h2').each(function() {
        the_id = $(this).attr('id');
        $('nav > ol').append('<li><a href="#' + the_id + '">' + $(this).text() + '</a></li>');
        $(this).siblings('h3').each(function(i) {
            the_id = $(this).attr('id');
            if (i == 0) {
                $('nav > ol > li:last').append('<ol></ol>');
            }
            $('nav > ol > li:last > ol').append('<li><a href="#' + the_id + '">' + $(this).text() + '</a></li>');
        });
    });
});
$('section')。每个(函数(){
var_id;
风险值清单项目;
$(this).find('h2').each(function(){
_id=$(this.attr('id');
$('nav>ol')。追加('li>');
$(this).同级('h3')。每个(函数(i){
_id=$(this.attr('id');
如果(i==0){
$('nav>ol>li:last')。附加('');
}
$('nav>ol>li:last>ol')。追加('
  • '); }); }); });
    它会生成一些HTML,如:

    <li>
       <a href="#example-1">Example 1</a>
       <ol>
          <li>
             <a href="#example-1a">Example 1a</a>
         </li>
         <li>
             <a href="#example-1b">Example 1b</a>
         </li>
       </ol>
    </li>
    <li>
       <a href="#another-example">Another Example</a>
    </li>
    <li>
      <a href="#last-one">Last One</a>
    </li>
    <li>
       <a href="#just-kidding--another">Just kidding, another</a>
       <ol>
          <li>
             <a href="#this-is-a-sub-header">This is a sub header</a>
          </li>
       </ol>
    </li>
    

  • 我的问题是,我的JS只在我写的时候起作用(h2,然后寻找H3,我必须为h4编写另一个回调,然后为h5和h6编写另一个回调。我如何才能编写一个递归函数来实现这一点?

    稍微看一下这个,我想我明白了你的目的。每个级别实际上并没有什么不同,你只是解释了最低级别来实现它。就像Matt一样的评论说,您需要单独声明回调。但您还需要将当前级别的列表传递到其中,以便可以附加到正确的位置。我们可以尝试一种使用方法构造回调的方法,如下所示:

    function Generator(e, level) {
        var list = e; // I think you need this for the closure to work, but my js is rusty so I may be wrong.
    
        return function() {
            var new_list = $('<ol></ol>');
            list.append(new_list); // you might want to make sure there's more than 0 siblings?
    
            $(this).siblings('h' + level).each(function(i) {
                the_id = $(this).attr('id');
                new_list.append('<li><a href="#' + the_id + '">' + $(this).text() + '</a></li>');
                if (level < 6) { // your max h tag level
                    Generator(new_list, level + 1)();
                }
            });
        }
    }
    
    显然,您的代码一开始使用的是
    $(this.find('h2')
    ,而不是
    $(this.this.)。兄弟姐妹('h2')
    ,因此需要在这方面进行一些调整。但我相信这不是什么大问题

    我没有测试这个,所以我可能在某个地方至少犯了一个错误。

    一个搜索结果显示:它是纯“ole javascript”,但您应该能够根据自己的需要调整它(或者,借用这个想法,编写自己的代码)

    在讨论了一些之后,我认为Juan是对的:迭代方法似乎更容易。我制作了一个使用类似方法的快速jQuery插件:

    (function($) {
        $.fn.buildTOC = function(options) {
            var opts = $.extend({
                    scan: $(document) // By default, search the entire page for headings
                }, options),
                $toc = $(this),       // This is where we'll place our TOC links
    
                /*
                * Get the current level from the Heading tag.
                */
                getLevel = function(h) {
                    return parseInt(h.substring(1));
                },
    
                /*
                 * Creates a new sublist and returns it.
                 * The randomly-generated ID just makes it easier to find the new list.
                 */
                pushLevel = function(toc) {
                    var id = 'node' + Math.round(Math.random() * 50000 + 1);
                    toc.append($('<ol id="' + id + '"></ol>'));
                    return $('#' + id, toc);
                },
    
                /*
                 * Returns the last sublist containing an element at the current level;
                 * otherwise, returns the parent list (for top-level items).
                 */
                popLevel = function(toc, level) {
                    var sub = $('.toc-level-' + level + ':last', toc);
                    if (sub.length) {
                        return sub.parent();
                    } else {
                        return $toc.children('ol');
                    }
                },
    
                /*
                 * Appends a link for the current tag to the current list.
                 * Also adds a class for the current level (handy for styling), so it's easy
                 * to find items at this level.
                 */
                appendLink = function(toc, tag, level) {
                    toc.append($('<li class="toc-level-' + level + '"><a href="#' + tag.id + '">' + tag.innerHTML + '</a></li>'))
                },
    
                buildTOC = function(toc) {
                    var headings = $('h1,h2,h3,h4,h5,h6', opts.scan),
                        lastLevel = 0;
                    for (var i=0, len=headings.length; i<len; i++) {
                        var currTag = headings[i],
                            currLevel = getLevel(currTag.tagName);
                        if (lastLevel == currLevel) {
                            // Siblings: just add a link for this item
                            appendLink(toc, currTag, currLevel);
                        } else if (lastLevel < currLevel) {
                            // Child: create a new list and append to that
                            toc = pushLevel(toc);
                            appendLink(toc, currTag, currLevel);
                        } else {
                            // Parent: move back out to the appropriate list
                            toc = popLevel(toc, currLevel);
                            appendLink(toc, currTag, currLevel);
                        }
                        lastLevel = currLevel;
                    }
                };
    
            buildTOC($toc);
        };
    })(jQuery);
    

    其中
    toc
    是链接应该放在哪里的容器ID。

    另一种构建列表HTML的方法如何?我在编写/理解递归代码方面真的很差劲。迭代通常对我来说更容易

    function buildToc(container) {
        var html = "", lastLevel = -1;
        container.find('h1, h2, h3, h4, h5, h6, h7, h8, h9').each(function() {
            var $this = $(this);
            var level = this.tagName.match(/H(\d)/)[1];
            if (lastLevel < level) {
                html += "<ol>";
            }
            if (lastLevel > level)  {
                html += "</ol>";
            }
            html += "<li><a href='"+ this.id + "' >" + $this.text() + "</a></li>";
            lastLevel = level;
        });
        return html;
    }
    $('nav').append( buildToc( $('article section') ) );
    
    函数buildToc(容器){
    var html=”“,lastLevel=-1;
    container.find('h1,h2,h3,h4,h5,h6,h7,h8,h9')。每个(函数(){
    var$this=$(this);
    变量级别=此.tagName.match(/H(\d)/)[1];
    如果(最后级别<级别){
    html+=“”;
    }
    如果(lastLevel>level){
    html+=“”;
    }
    html+=“
  • ”; lastLevel=level; }); 返回html; } $('nav').append(buildToc($('article section'));

    我在你的页面上运行了它,它复制了你现有的TOC。你不需要为每一个级别编写自定义代码;快速而肮脏。

    如果你单独声明回调函数,而不是匿名声明回调函数,那么用JavaScript编写递归函数就很容易了。但是,我看不出递归在这里有什么帮助,因为它看起来逻辑不同对于每个标题级别都是t。对于“s”之后的所有内容都是相同的。它始终是同级的,但是ol>li x,不管你在什么位置。为什么是递归的?也许你的问题是为什么不
    $(“h*”)
    工作,我怎样才能得到相同的效果,一组所有的h1,h2,h3,…?你说的最后一位是什么意思,
    ol>li x
    ?我知道这是一个选择器,但我知道你不仅仅是指H4的
    ol>li 4
    。它需要以
  • 的方式嵌套所有内容。也就是说,将所有内容都放在一个div中,然后通过该d进行下去iv对于所有sub在抓取所有sub之后,返回到s并进入div抓取所有sub hx,等等。这是一个ToC:你不应该有一个只包含链接的答案。你应该在这里简单地解释一下。代码看起来很棒,它会工作,但这是很多代码。这应该是一个简单的递归函数,比如Tesserexp,我还在测试。@Juan,@Oscar:很对,伙计们……我正在研究:)顺便说一句,我认为Tesserex的功能也很好。更接近,我认为,--除了“示例1”、“另一个示例”、“最后一个”和“开玩笑”看起来不太正确之外都是兄弟姐妹,而不是示例1的后代。递归函数让我的大脑爆炸;)也请看我对JS模板的评论!
    $(function() {
        $('#toc').buildTOC();
    })
    
    function buildToc(container) {
        var html = "", lastLevel = -1;
        container.find('h1, h2, h3, h4, h5, h6, h7, h8, h9').each(function() {
            var $this = $(this);
            var level = this.tagName.match(/H(\d)/)[1];
            if (lastLevel < level) {
                html += "<ol>";
            }
            if (lastLevel > level)  {
                html += "</ol>";
            }
            html += "<li><a href='"+ this.id + "' >" + $this.text() + "</a></li>";
            lastLevel = level;
        });
        return html;
    }
    $('nav').append( buildToc( $('article section') ) );