Книга: JavaScript. Подробное руководство, 6-е издание
15.7. Пример: создание оглавления
15.7. Пример: создание оглавления
Пример 15.7 показывает, как динамически создавать оглавление документа. Он демонстрирует многие концепции работы с документом, описанные в разделах выше: выбор элементов, навигация по документу, установка атрибутов элементов, установка свойства innerHTML
и создание новых узлов и вставку их в документ. Пример снабжен большим количеством комментариев, которые призваны облегчить понимание программного кода.
Пример 15.7. Автоматическое создание оглавления документа
/**
* TOC.js: создает оглавление документа.
*
* Этот модуль регистрирует анонимную функцию, которая вызывается
* автоматически по окончании загрузки документа. Эта функция сначала
* отыскивает элемент документа с атрибутом. Если такой элемент
* отсутствует, функция создает его, помещая в начало документа.
*
* Затем функция отыскивает все элементы с <h1> по <h6>, интерпретируя их как
* заголовки разделов и создает оглавление внутри элемента ТОС. Функция добавляет
* номера разделов в каждый заголовок и обертывает заголовки именованными
* якорными элементами, благодаря чему оглавление может ссылаться на них.
* Якорным элементам даются имена, начинающиеся с приставки "ТОС", поэтому вам следует
* избегать использовать эту приставку в своей разметке HTML.
*
* Оформление элементов оглавления можно реализовать с помощью CSS. Все элементы имеют
* класс "TOCEntry". Кроме того, каждый элемент оглавления имеет класс, соответствующий
* уровню заголовка раздела. Для заголовков, оформленных тегом <h1>, создаются элементы
* оглавления с классом "TOCLevell",для заголовков <h2> - с классом "T0CLevel2" и т. д.
* Номера разделов, вставляемые в заголовки, получают класс "TOCSectNum".
*
* Этот модуль можно использовать с каскадными таблицами стилей, такими как:
*
* #Т0С { border: solid black 1рх; margin: Юрх; padding: Юрх; }
* .TOCEntry { font-family: sans-serif; }
* .TOCEntry a { text-decoration: none; }
* .TOCLevell { font-size: 16pt; font-weight: bold; }
* .T0CLevel2 { font-size: 12pt; margin-left: .5in; }
* .TOCSectNum:after { content: "; }
*
* Последнее определение генерирует двоеточие и пробел после номера раздела.
* Чтобы скрыть номера разделов, можно использовать следующий стиль:
*
* .TOCSectNum { display: none }
*
* Этот модуль использует вспомогательную функцию onLoad().
**/
onLoad(function() { // Анонимная функция, определяющая локальн. обл. видимости
// Отыскать контейнерный элемент для оглавления.
// Если такой элемент отсутствует, создать его в начале документа,
var toc = document.getElementById("TOC");
if (!toc) {
toc = document.createElementC'div");
toc.id = "TOC";
document.body.insertBefore(toc, document.body.firstChild);
}
// Отыскать все элементы заголовков разделов
var headings;
if (document.querySelectorAll) // Возможно есть более простой путь?
headings = document.querySelectorAll(”h1,h2,h3.h4, h5. h6”);
else // Иначе отыскать заголовки более сложным способом
headings = findHeadings(document.body, []);
// Выполняет рекурсивный обход тела документа в поисках заголовков
function findHeadings(root, sects) {
for(var с = root.firstChild; c != null; c = c.nextSibling) {
if (c.nodeType !== 1) continue;
if (c.tagName.length == 2 && c.tagName.charAt(O) == "H")
sects.push(c);
else
findHeadings(c, sects);
}
return sects;
}
// Инициализировать массив, хранящий номера разделов,
var sectionNumbers = [0,0,0,0,0,0];
// Выполнить цикл по найденным элементам заголовков.
for(var h = 0; h < headings.length; h++) {
var heading = headings[h];
// Пропустить заголовки, находящиеся в контейнере оглавления,
if (heading.parentNode == toc) continue;
// Определить уровень заголовка.
var level = parseInt(heading.tagName.charAt(1));
if (isNaN(level) || level < 1 || level > 6) continue;
// Увеличить номер раздела для этого уровня и установить
// номера разделов более низкого уровня равными нулю.
sectionNumbers[level-1]++;
for(var і = level; і < 6; і++) sectionNumbers[i] = 0;
// Объединить номера разделов всех уровней,
// чтобы получился номер вида 2.3.1.
var sectionNumber = sectionNumbers.slice(0,level).join(".")
// Добавить номер раздела в заголовок. Номер помещается в элемент <span>,
// чтобы его можно было стилизовать с помощью CSS.
var span = document.createElement("span");
span.className = "TOCSectNum";
span.innerHTML = sectionNumber;
heading.insertBefore(span, heading.firstChild);
// Обернуть заголовок якорным элементом, чтобы можно было
// сконструировать ссылку на него.
var anchor = document.сreateElement("а");
anchor.name = "TOC"+sectionNumber;
heading.parentNode.insertBefore(anchor, heading);
anchor.appendChild(heading);
// Создать ссылку на этот раздел,
var link = document.createElement("а");
link.href = "#T0C" + sectionNumber; // Адрес назначения ссылки
link.innerHTML = heading.innerHTML; // Текст ссылки совпадает
// с текстом заголовка
// Поместить ссылку в элемент div, чтобы обеспечить возможность
// стилизации в зависимости от уровня.
var entry = document.сreateElement("div");
entry.className = "TOCEntry TOCLevel" + level;
entry.appendChild(link);
// И добавить элемент div в контейнер оглавления,
toc.appendChild(entry);
}
});
- 15.1. Обзор модели DOM
- 15.2. Выбор элементов документа
- 15.3. Структура документа и навигация по документу
- 15.4. Атрибуты
- 15.5. Содержимое элемента
- 15.6. Создание, вставка и удаление узлов
- 15.7. Пример: создание оглавления
- 15.8. Геометрия документа и элементов и прокрутка
- 15.9. HTML-формы
- 15.10. Другие особенности документов
- Создание и редактирование стилей
- Создание титульной страницы
- Практическая работа 35. Создание структуры документа и вставка оглавления
- Пример 12-1. Создание оглавления диска для записи CDR, с помощью команды ls
- 13.3.9. Создание оглавления
- Пример установочного скрипта
- Пример из практики
- Создание файлов с блокировкой
- ПРИМЕР ПРОСТОЙ ПРОГРАММЫ НА ЯЗЫКЕ СИ
- Создание свободно позиционируемых элементов
- Примеры получения статистики
- Пример применения метода «пять почему»