Любые хорошие коды для генерации оглавления из элементов заголовка HTML в JavaScript? - PullRequest
3 голосов
/ 28 апреля 2011

Я хотел бы создать оглавление, как показано ниже в JavaScript:

<ol>
  <li>Heading 1</li>
  <li>Heading 2
    <ol>
      <li>Heading 2-1</li>
      <li>Heading 2-2</li>
    </ol>
  </li>
  <li>Heading 3</li>
</ol>

И HTML-коды для генерации оглавления выше:

<section id="toc">
  <p>This will be replaced with generated TOC.
</section>

<article>
  <h1>Heading 1<h1>
  <p>Bla bla bla.</p>

  <h1>Heading 2<h1>
  <p>Bla bla bla.</p>

    <h2>Heading 2-1<h2>
    <p>Bla bla bla.</p>

    <h2>Heading 2-2<h2>
    <p>Bla bla bla.</p>

  <h1>Heading 3<h1>
  <p>Bla bla bla.</p>
</article>

Я действительно застрял :( Как вы пишете код для генерации оглавления? Я предпочитаю jQuery или чистый JavaScript.

UPDATE

Это было довольно тяжело для меня, но как-то, я полагаю, я сделал:

  $(function () {
    var assigned_level = 0,
        current_level = 0,
        id_number = 1,
        parent_node = "article",
        toc_html = '';

    $(parent_node + " *").each(function () {
      if (this.nodeName.length === 2 && this.nodeName.charAt(0) === "H") {
        $(this).attr("class", "heading");
      }
    });

    $(".heading").each( function () {
      current_level = this.nodeName.charAt(1);

      $(this).attr('id', "toc-" + id_number);

      // Close a list if a same level list follows.
      if (assigned_level !== current_level - 1) {
        toc_html += "</li>"
      }

      // Open parent lists if a child list follows.
      while (assigned_level < current_level) {
        toc_html += "<ol>";
        assigned_level += 1;
      }

      // Close child lists and the parent list if
      // the same level parent list follows.
      while (assigned_level > current_level) {
        toc_html += "</ol></li>";
        assigned_level -= 1;
      }

      toc_html += 
        '<li><a href="#' + this.id + '">' + $(this).html() + "</a>";
      id_number += 1;
    });

    // Close everything
    while (assigned_level > 0) {
      toc_html += "</li></ol>";
      assigned_level -= 1;
    }

    $("#toc").html(toc_html);
  });

Я до сих пор не понимаю, что я сделал: P Возможно, есть более сложные способы. Пожалуйста, укажите мне все, что вы нашли.

Спасибо.

Ответы [ 2 ]

4 голосов
/ 28 апреля 2011

Прежде всего, вам необходимо закрыть теги h1, h2 =)

если вы сделаете $("h1, h2, h3, h4, h5, h6"), вы получите теги в том же порядке, в котором они появляются в документе. Таким образом, вы можете сделать цикл в этом массиве и проверить уровень. Например: если последний тег был H1 и вы нашли H2, это означает, что вам нужно создать <ol>. С другой стороны, если у вас H3, а следующий - H2, это означает, что вам нужно закрыть <ol>.

Самое сложное - закрыть оставшиеся <ol> в конце.

Надеюсь, это поможет.

1 голос
/ 28 апреля 2011

Не хочу сейчас углубляться, пока мы не увидим, что вы придумали.

Однако посмотрите на .each () .children () и .find () . Это должно дать вам некоторые идеи о том, как выполнить то, что вы хотите сделать.

...