Последнее обновлене - 29 октября 2024 в 15:56
В этой заметке остановлюсь на том, как сделать оглавление с подпунктами на сайте без плагина. Это будет расширенная версия кода, который позволяет внедрить оглавление с одними только пунктами.
При помощи нового кода, на сайте WordPress в записях будет появляться оглавление, если в этих записях будут присутствовать подзаголовки, обозначаемые тегами H2 и H3. Кроме того, оглавление должно открываться при клике на него и закрываться (сворачиваться). Также мне нужна плавная прокрутка до подзаголовков при клике по пункту в оглавлении.
Для добавления оглавления к записям WordPress, если в них присутствуют заголовки H2 и H3, и чтобы оглавление можно было сворачивать/разворачивать при клике, а также обеспечить плавную прокрутку до подзаголовков при клике по пункту оглавления, нужно сделать следующее:
- Добавить JavaScript для генерации оглавления и функционала сворачивания/разворачивания.
- Добавить CSS для стилизации оглавления и его фона.
- Добавить PHP код, чтобы подключить скрипты и стили к записям WordPress.
Шаг 1: JavaScript. Создадим JavaScript-файл table-of-contents.js:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
document.addEventListener("DOMContentLoaded", function() { const headings = document.querySelectorAll(".entry-content h2, .entry-content h3"); if (headings.length === 0) return; let toc = document.createElement('div'); toc.className = 'toc-wrapper'; let tocTitle = document.createElement('div'); tocTitle.className = 'toc-title'; tocTitle.innerHTML = 'Оглавление'; tocTitle.addEventListener('click', function() { toc.classList.toggle('open'); }); let tocList = document.createElement('ul'); tocList.className = 'toc-list'; headings.forEach((heading, index) => { let tocItem = document.createElement('li'); tocItem.className = `toc-item toc-${heading.tagName.toLowerCase()}`; let tocLink = document.createElement('a'); tocLink.innerHTML = heading.innerHTML; tocLink.href = `#toc-${index}`; tocLink.addEventListener('click', function(e) { e.preventDefault(); document.querySelector(tocLink.getAttribute('href')).scrollIntoView({ behavior: 'smooth' }); }); tocItem.appendChild(tocLink); tocList.appendChild(tocItem); heading.id = `toc-${index}`; }); toc.appendChild(tocTitle); toc.appendChild(tocList); document.querySelector(".entry-content").prepend(toc); }); |
Шаг 2: CSS. Создадим CSS-файл table-of-contents.css:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
.toc-wrapper { border: 1px solid #ccc; background-color: #f9f9f9; margin-bottom: 20px; padding: 10px; border-radius: 4px; max-width: 300px; position: relative; overflow: hidden; transition: max-height 0.3s ease; } .toc-wrapper.open { max-height: 1000px; /* large value to accommodate content */ } .toc-wrapper:not(.open) { max-height: 40px; /* height of the title bar */ } .toc-title { font-weight: bold; cursor: pointer; padding: 5px; background-color: #0073aa; color: #fff; border-radius: 4px; text-align: center; } .toc-list { list-style: none; padding: 0; margin: 0; display: none; } .toc-wrapper.open .toc-list { display: block; } .toc-item { margin: 5px 0; } .toc-item a { text-decoration: none; color: #0073aa; } .toc-item a:hover { text-decoration: underline; } /* Стили для иерархии заголовков */ .toc-h2 { font-weight: bold; } .toc-h3 { padding-left: 20px; /* Отступ для подзаголовков */ font-weight: normal; /* Уменьшаем вес шрифта для подзаголовков */ } |
Шаг 3: PHP. Добавим PHP код в файл темы WordPress (например, functions.php), чтобы подключить наши скрипты и стили:
1 2 3 4 5 6 7 |
function enqueue_toc_scripts() { if (is_single()) { wp_enqueue_script('toc-js', get_template_directory_uri() . '/js/table-of-contents.js', array(), null, true); wp_enqueue_style('toc-css', get_template_directory_uri() . '/css/table-of-contents.css'); } } add_action('wp_enqueue_scripts', 'enqueue_toc_scripts'); |
Финальная настройка состоит в следующем:
- Создадим папки js и css в корневом каталоге рабочей темы WordPress (если они ещё не существуют).
- Сохраним JavaScript-файл в папку js под именем table-of-contents.js.
- Сохраним CSS-файл в папку css под именем table-of-contents.css.
- Добавим PHP-код в functions.php рабочей темы.
Такое оглавление будет выводиться в самом начале поста, перед текстом. В том случае, если требуется установить оглавление после первого абзаца текста, нужно немного изменить JavaScript-код.
Посмотрим на модифицированный JavaScript-файл table-of-contents.js. Вот как будет выглядеть обновленный код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
document.addEventListener("DOMContentLoaded", function() { const headings = document.querySelectorAll(".entry-content h2, .entry-content h3"); if (headings.length === 0) return; let toc = document.createElement('div'); toc.className = 'toc-wrapper'; let tocTitle = document.createElement('div'); tocTitle.className = 'toc-title'; tocTitle.innerHTML = 'Оглавление'; tocTitle.addEventListener('click', function() { toc.classList.toggle('open'); }); let tocList = document.createElement('ul'); tocList.className = 'toc-list'; headings.forEach((heading, index) => { let tocItem = document.createElement('li'); tocItem.className = `toc-item toc-${heading.tagName.toLowerCase()}`; let tocLink = document.createElement('a'); tocLink.innerHTML = heading.innerHTML; tocLink.href = `#toc-${index}`; tocLink.addEventListener('click', function(e) { e.preventDefault(); document.querySelector(tocLink.getAttribute('href')).scrollIntoView({ behavior: 'smooth' }); }); tocItem.appendChild(tocLink); tocList.appendChild(tocItem); heading.id = `toc-${index}`; }); toc.appendChild(tocTitle); toc.appendChild(tocList); // Находим первый абзац и вставляем оглавление после него const firstParagraph = document.querySelector(".entry-content p"); if (firstParagraph) { firstParagraph.insertAdjacentElement('afterend', toc); } }); |
Объяснение изменений: вместо того чтобы добавлять оглавление в начало .entry-content, мы находим первый абзац с помощью document.querySelector(«.entry-content p») и используем метод insertAdjacentElement(‘afterend’, toc), чтобы вставить оглавление сразу после первого абзаца.
Теперь при просмотре записей WordPress, если они содержат подзаголовки H2 и H3, будет автоматически генерироваться оглавление с возможностью сворачивания/разворачивания и плавной прокруткой к подзаголовкам при клике.
Всем WEB!
Ух ты, надо попробовать с подпунктами оглавление.
Напишите потом, получилось или нет.