Научный консалтинг
Главная
Контакты
Номер телефона
Как мы работаем
Гарантии
Условия
Цены

Как расставить номера заголовков в тексте страницы html

Заголовки на вебстраницах служат для обозначения смысловых частей текста. Заголовок включает в себя краткое содержание документа. Он должен быть согласован с названием страницы и может может отвечать на вопросы:

  • о чем (о ком)?
  • для чего (кого)?
  • где?

и т.д. Заголовки служат также для привлечения и акцентирования внимания посетителей. Наконец, они используются и для поисковой оптимизации страницы в выдаче Яндекс, Google, Bing и т.д.

Заголовки обозначаются тегами вида <h1>, <h2>,… , <h6>. Чем более общим и/или важным является заголовок, тем ниже его «номер», т.е. тем ближе он к <h1>.

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

Нередко у вебмастера стоит задача: правильно проставить номера заголовков. Например, имеется следующее содержание:

  1. Введение
  2. Теоретические аспекты
  3. Практическая часть
  4. Мероприятия и предложения
  5. Приложения

Каждому из заголовков в статье соответствует свой (соответствующий) раздел.

Здесь заголовки перенумерованы по порядку. Возникает вопрос: каким образом синхронизировать нумерацию заголовков в оглавлении с нумерацией в самой статье? Т.е. чтобы заголовок раздела «Практическая часть» имел номер как в оглавлении, так и в статье, равный 2; заголовок «Мероприятия и предложения» - имел бы номер 3 и т.д.

Конечно, можно сделать это вручную. Но, для больших статей возможны несовпадения. Можно воспользоваться каким-нибудь плагином или библиотекой.

В этой статье мы рассмотрим простой пример подобного «плагина», работающего на стороне клиента (т.е. в браузере, на языке javascript), проставляющего номера заголовков в статье в точном соответствии с их номерами в оглавлении.

Вначале оформляем оглавление

Вариантов оформления оглавления, конечно, может быть множество. Вот один из них:

<ol id="ol">
   <li><a href="#li1">Введение</a></li>
   <li><a href="#li2">Теоретические аспекты</a></li>
   <li><a href="#li3">Практическая часть</a></li>
   <li><a href="#li4">Мероприятия и предложения</a></li>
   <li><a href="#li5">Приложения</a></li>
</ol>

Как видим, каждый из пунктов списка ol содержит ссылку с названием заголовка. При нажатии на нее происходит переход к соответствующему разделу. Номер заголовка задается в списке автоматически.

По умолчанию, номер первого пункта будет равным 1. Однако, его можно изменить, применив свойство start. Например, сделав

<ol id="ol" start="3">

нумерация списка начнется уже не с первого, а с третьего пункта. Т.е. введение будет нумероваться цифрой 3. Теоретические аспекты – цифрой 4 и т.д.

Задаем идентификаторы id у заголовков в тексте статьи

Чтобы было возможно переходить сразу к требуемым разделам на странице, необходимо, чтобы каждый из заголовков имел свой уникальный (в пределах вебстраницы) идентификатор id. Обычно их задают так, чтобы по звучанию можно было догадаться, о каком именно заголовке идет речь.

Создаем код javascript

Создаем код javascript для автоматической расстановки номеров заголовков в тексте статьи. Вначале приведем его, а затем проанализируем:

<script type="text/javascript">
   /* <!-- [CDATA [*/
var i; var j=0;
var links = new Array();
   var spisok_ol = document.getElementById("ol");
var elements = spisok_ol.childElementCount;
var href_ol;
   // Получаем массив из атрибутов "href" ссылок, содержащихся в списке
for(i=0; i<elements; i++){
   if(spisok_ol.getElementsByTagName("li")[i].nodeName == "LI") {
links[j] = spisok_ol.children[i].getElementsByTagName("a")[0].getAttribute("href").substring(1);
   j++;
   }
}
var elements_len_1 = links.length-1;

   for(var k=1; k<7; k++) {
       // Получаем все теги h1...h6 из списка с id="ol"
       
var h = document.getElementsByTagName("h" + k);
       var h_num_1 = h.length-1;

       
for (j = elements_len_1; j >= 0; j=j-1) {
             for (i = h_num_1; i >= 0; i=i-1) {
               href_ol = links[j];
               if (h[i].getAttribute("id") === href_ol) {
                   if (isInteger(h[i].textContent.substring(0, 1))) {
                     //  continue;  //(если необходимо пропускать номера заголовков, на которые сделано более 1 ссылки)
                   
}

                   href_ol = h[i].textContent;
                   h[i].textContent = j + 1 + ". " + href_ol;
                   break;
               }
           }
       }
   }

   function isInteger(num) {
       return ((num ^ 0) === num*1);
   }
   /*]] --> */
</script>


Вот такой небольшой код. Он является полностью рабочим, должен работать и в тех браузерах, которые были написаны лет 5…6 назад и даже ранее.

Вы можете вставить его к себе прямо на страницу. Или возможно подключить его обычным образом, например, так:

<script src="http://www.site.ru/number.js" charset="utf-8" type="text/javascript"></script>

При этом указанный выше код должен быть помещен в файл с именем number.js . Этот файл должен быть расположен в каталоге /www.site.ru/. Конечно, можно поместить его в любой другой каталог сайта – по надобности.

Примечание. Если Вы решите применить последний способ, то не забудьте, что в файл number.js следует скопировать почти весь код, за исключением, естественно, самих тегов <script> и </script>.

Если Вас не интересует, как же работает приведенный выше код javascript, дальше можете не читать. А вот кому интересно – пойдемте дальше!

Разбор работы кода

Вначале, как видим, имеются комментарии

   /* <!-- [CDATA [*/

и

   /*]] --> */

Они имеют значение, если сайт разработан согласно стандарта XHTML. В таком случае, раздел CDATA означает место в html-коде вебстраницы, в которое может быть записана, вообще говоря, произвольная информация.

Правда, как увидим ниже, не совсем произвольная.

В частности, если html-страница содержит код javascript, то последний должен содержаться в разделе CDATA – таково правило, накладываемое стандартом XHTML.

Так как данный раздел CDATA не будет присутствовать на дисплее, полагается брать управляющие символы, обозначающие этот раздел, в комментарии html (т.е., по сути, имеем примерно следующее, если в одну строчку):

<!-- [CDATA [*/       …      /*]] -->

Однако, так как раздел находится между тегами <script>, обозначающими место, где находится javascript-код, то, чтобы браузер не начал пытаться выполнять то, что находится в данном разделе, его необходимо закомментировать, но уже по правилам javascript. Как Вы помните, если в html комментарии реализуются при помощи символов

<!-- Комментарий   -->

то в javascript комментирование делается так:

/*  Комментарий  */

Однако, если закомментировать ВЕСЬ раздел CDATA в javascript, то последний выполняться вообще не будет. Поэтому в комментарии оформляются только      <!-- [CDATA [  и ]] --> .

Если же сайт сделан на html5, то указанные нюансы с комментированием будут излишними; однако, если они будут, то не повредят: браузер просто проигнорирует их, и все.

Строчка

var spisok_ol = document.getElementById("ol");

получает содержимое списка, имеющего идентификатор id="ol" в виде списка его элементов (в данном случае – тегов <li>). Затем подсчитывается число этих элементов.

Цикл

for(i=0; i<elements; i++){
...
}

формирует массив links[], в котором содержатся якоря ссылок, содержащихся в тегах <li> списка.

Функция

substring(1)

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

Далее циклом

for(var k=1; k<7; k++) {
...
}

производим перебор всех тегов h1...h6. Перебор производится с учетом особенностей работы javascript с символьными и целыми типами данных: название тега формируется как

"h" + k

где k – целое число в диапазоне от 1 до 6. Например, если k=3, то название тега будет “h3”.

Затем для каждого из тегов h1…h6 (в соответствующей итерации цикла) производится сопоставление якорей, содержащихся в ссылках, присутствующих в списке и значения id заголовков в тексте статьи. При совпадении – в заголовок дописывается номер (и еще точка с пробелом), соответствующий положению тега <li> со соответствующей ссылкой в списке.

Подробнее

При этом циклом

for (j = elements_len_1; j >= 0; j=j-1) {

}

производится перебор каждого из значений якорей (которые, как мы видели, содержатся в массиве links[]). Для каждого из значений якоря по html-коду страницы производится поиск заголовка, имеющего идентификатор id, значение которого равно значению якоря. Поиск этот производится при помощи цикла

for (i = h_num_1; i >= 0; i=i-1) {

}

Обратите внимание, что цикл работает «нестандартно»: не с начала (как делается в 99% случаев), а с конца. Если бы цикл работал с начала, он бы выглядел примерно так:

for (i = 0; i <= h_num_1; i++) {

}

Однако, для чего принят обратный порядок выполнения цикла? Дело в том, что некоторые ссылки (более одной) могут ссылаться на одни и те же заголовки в тексте статьи. Если воспользоваться вышеприведенным примером оглавнения, предположим, что ссылки «Введение» (под номером 1) и «Теоретические аспекты» (под номером 2) ссылаются на один и тот же заголовок. В таком случае, очевидно, ссылки будут иметь одно и то же значение якоря:

<li><a href="#li1">Введение</a></li>
<li><a href="#li1">Теоретические аспекты</a></li>

Пусть заголовок может иметь, например, следующий вид:

<h3 id="li1">Введение и теоретические аспекты … </h3>

Тогда целесообразно добавить к заголовку номера 1 и 2. Так вот, если цикл будет осуществляться в прямом направлении (т.е., начиная с i = 0), то вначале к тексту заголовка добавится номер 1 (плюс, как уже говорилось, точка с пробелом) и он примет вид:

<h3 id="li1">1. Введение и теоретические аспекты … </h3>

Затем, после увеличения счетчика цикла, на следующей итерации, будет добавлен, очевидно, номер 2:

<h3 id="li1">2. 1. Введение и теоретические аспекты … </h3>

Согласитесь, получается как-то неудобно. Если же перебирать значения якорей ссылок в списке оглавления в обратном порядке, то вначале, наоборот, будет добавлен номер 2, затем – номер 1, т.е. заголовок примет вид:

<h3 id="li1">1. 2. Введение и теоретические аспекты … </h3>

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

Кстати, а почему в циклах вместо, казалось бы, общеизвестного

i--

применено

i=i-1

Дело в том, что унарный оператор -- воспринимается валидатором как часть ограничителя комментариев в коде html. В итоге, валидатор выдает сообщение вида

"Check that you are using a proper syntax for your comments, e.g: <!-- comment here -->. This error may appear if you forget the last "--" to close one comment, and later open another. "

Иными словами, валидатору кажется, что разработчик кода страницы хотел сделать комментарий, но неверно указал его ограничительную часть. Т.е. валидатор считает, что вместо унарного оператора -- должно быть либо

<!--

либо

-->

Конечно, «можно» не обращать внимания на сообщения валидатора. В самом деле, иной раз современные сайты грешат немалым количеством ошибок, нередко - существенных и… «ничего», типа того, как-то там работают. Собственно, в частности, потому-то они и тормозят при открытии, потому и работают некорректно в некоторых случаях. Поэтому – не стоит делать вебстраницы с ошибками. Всегда следует добиваться идеальной чистоты кода – как html, так и javascript. Хотя, стоит отметить, что в данном случае – это не ошибка в коде, а недоработка алгоритма валидации.

Кроме того, отметим, что если Вы разместите приведенный выше javascript-код не на самой html-странице, а в подключаемом файле js (как было описано выше), то валидатор сообщение об этой ошибке выдавать не будет.

По всей видимости, указанный нюанс объясняется ошибочным функционированием алгоритма работы валидатора.

Итак, в третьем цикде производится, путем перебора, сопоставление значения якоря соответствующей ссылки с идентифиактором (id) того или иного заголовка. Как только такое соответствие найдено, к заголовку, как уже говорилось, слева дописывается номер ссылки. Если соответствие для конкретного якоря будет найдено не один раз, номера ссылок будут также дописаны в левую часть текста заголовка.

Функция

isInteger(num)

служит для определения, является ли переменная num целым числом. Ее применение оправдано в случае, если необходимо ставить не более одного номера для каждого из заголовков в тексте статьи и, соответственно, пропускать значения якорей ссылок, которые ссылаются на заголовки. уже имеющими номера.

Так как номер (в частности, его первая цифра) представляет собой целое число, данная функция помогает определить, имеется ли у заголовка номер. Если да, то не дописываем (очередной) номер и переходим к следующей итерации цикла (при помощи операции continue). Но, так как было решено добавлять номера всех ссылок, якоря которых совпадают с идентификатором заголовка, поэтому операция continue – закоментирована.

Таким образом, перебирая все теги заголовков <h1>…<h6>, для каждого из них – перебирая массив якорей ссылок оглавления и сравнивая значения этих якорей с идентификаторами заголовков, можно автоматически расставить номера в заголовках по тексту статьи.

Естественно, скрипт должен запускаться в процессе загрузки страницы. Точнее, в самом конце загрузки (когда, собственно, сформировано дерево DOM и появились теги заголовков). Кроме того, расстановка номеров заголовков – это операция второстепенной важности. Поэтому следует ее выполнять почти в последнюю очередь, когда страница загрузилась, сфомировалась и пользователь уже читает ее.

Замечание. Однако, следует выполнять эту операцию, все же, ДО того, как выполнятся тяжелые, медленно работающие коды javascript. К таковым, например, относятся скрипты, находящиеся на сторонних ресурсах, загрузка которых происходит медленно. Это, скажем, счетчики количества посещений, реклама, баннеры и др.

Вот что мы можем сделать для Вас:
Интересная и полезная
информация
Изменить размер шрифта:
?