Админ

пятница, 29 апреля 2016 г.

Скрипт jQuery для автоматической сборки оглавления (в том числе в Blogger)

|
Довольно долго я мучился с движком Blogger: хотелось делать в начале длинных статей оглавление со ссылками. Вручную собирать оглавление, во-первых, хлопотно, во-вторых, у Blogger'а имеется такая странная особенность: для любых внутренних ссылок в документе нужно обязательно прописывать полный URL, иначе при сохранении статьи он автоматически подставляет перед знаком «#» адрес «https://www.blogger.com/blogger.g?blogID=…», и она, конечно, не работает. А указание в ссылке полного URL приводит к тому, что при щелчке на ней страница перезагружается целиком, что изрядно раздражает.

В конце концов я всё-таки написал простой скрипт (jQuery), который автоматически генерирует оглавление статьи, собирая его из заголовков (тегов <H1>,<H2> и т. д.) в указанной части текста и автоматически же вставляет внутренние ссылки. Это действительно простой скрипт, в интернете можно найти более впечатляющие примеры, когда оглавление постоянно находится на экране, в нём автоматически выделяются текущие элементы и т. д. Достаточно набрать в Google «jquery table of contents».


Источником вдохновения послужил написанный мною в далёком 2009 году скрипт на JavaScript (тогда ещё не jQuery), генерировавший структурированное оглавление в виде вложенных списков (увы, ссылка на статью про этот скрипт бесследно исчезла с того сайта, где она была выложена, и исходники нигде не сохранились) и статья Janko Jovanovic. В комментариях к той статье, кстати, предлагается похожее решение, но оно мне показалось слишком длинным и громоздким.

Получившийся скрипт генерирует не просто набор ссылок (как у Janko), а структурированный список с правильными уровнями вложенности. Отдельно обрабатываются ситуации, когда иерархия заголовков нарушена, то есть, например, после заголовка H1 сразу идёт H3.

В принципе, Blogger тут вообще ни при чём, работать этот скрипт может везде, где подключается jQuery. В качестве проверки я вставил его в последние по времени пару статей: про планшетный компьютер и про SQL-запросы для Firebird: эти статьи самые длинные, и без оглавления их тяжело читать.

$(function() {
  var curlvl;
  var startlvl = 0; // 2 for Blogger
  var prevlvl = startlvl;
  var lst = $("#toc");
  if(typeof lst !== "undefined") {
    $("#content h1, #content h2, #content h3, #content h4").each(function(i) {
      var current = $(this);
      current.attr("id", "title" + i);    
      for(curlvl = parseInt(current.prop("tagName").substring(1)); curlvl > prevlvl; prevlvl++) {
        var tmp = $("<ul></ul>");
        if(prevlvl == startlvl)
          lst.append(tmp);
        else {
          var last_li = $("#toc li").last();
          last_li.append(tmp);
        }
        if (curlvl > prevlvl + 1)
          tmp.append("<li style=\"list-style-type: none\"></li>");
        lst = tmp;
      }
      while(curlvl < prevlvl) {
        lst = lst.parent().parent();
        prevlvl--;
      }
      lst.append("<li><a id='link" + i + "' href='#title" + i + "'>" + current.html() + "</a></li>");
    });
  }
});
Здесь startlvl — это фактически константа, которая определяет «нулевой» уровень вложенности (да, я знаю про ключевое слово const, но мне всё-таки хотелось сохранить совместимость с IE). Например, в статьях Blogger обычно используются заголовки уровней 3 и 4 (1 и 2 используются на главной странице блога), поэтому startlvl = 2, а заголовки, которые необходимо учитывать, будут записаны как "#content h3, #content h4".

Перед использованием скрипта текст статьи нужно подготовить. Во-первых, нужно выбрать место для оглавления и вписать в этом месте <div id="toc"></div>. Во-вторых, окружить ту часть статьи, из которой должно быть собрано оглавление, тегом <div id="content">…</div>. Всё остальное сделает скрипт.

1 комментарий:

Пожалуйста, не используйте в сообщениях ненормативную лексику и нарушающие закон темы

Insert Emoticons
:))
:((
:D
:(
=))
b-(
:)
:P
:-o
:*
:-s
[-(
@-)
=d>
b-)
:-?
:->
X-(

К началу