Автор: Stasyuk Eugene 68 Мітки: 06.06.2022

Що це?

На деяких сайтах періодично можна зустріти щось подібне:

nav

Працює ця штука так:

  • Кожен пункт вмісту – це заголовок статті h2, h3, h4…
  • Клікаючи на якийсь із цих пунктів ми переміщуємося за допомогою якірного посилання в необхідну нам область сторінки.
  • Також, коли ми перегортаємо сторінку і в поле зору користувача потрапляє певна область із заголовком, цей пункт навігації якимось чином підсвічується, даючи зрозуміти де ми знаходимося.

Завантажити готовий файл можна за цією посиланням

Як це працює?

А тепер розберемо все поетапно. Збиратимемо файл скрипта по шматках.

Розмітка нашої навігації буде виглядати так:

<ul>
	<li>
		<a href="#article_title1">Title H2</a>
		<ul>
			<li>
				<a href="#article_title2">Title H3</a>
			</li>
			<li>
				<a href="#article_title3">Title H4</a>
			</li>
		</ul>
	</li>

	<li>
		<a href="#article_title4">Title H2</a>
		<ul>
			<li>
				<a href="#article_title5">Title H3</a>
			</li>
			<li>
				<a href="#article_title6">Title H4</a>
			</li>
		</ul>
	</li>
</ul>

Як видно з прикладу, наша навігація матиме вкладеність.

1) Створюємо змінну, в яку поміщаємо заголовки контенту необхідної нам області:

const titles = document.querySelector('.post-content__content .text').querySelectorAll('h2,h3,h4');

2) Додаємо до наших заголовків id:

let i = 0;
titles.forEach(title=>{
    title.setAttribute('id', `articles_title${i}`);
    i++;
});

3) Створюємо об’єкт та змінну, які допоможуть нам зробити вкладеність

let titlesObj = {},
        h2;

for(let i = 0; i < titles.length; i++){

    if(titles[i].classList.contains('no-active')){
        continue;
    }

    if(titles[i].tagName == 'H2'){
        titlesObj[titles[i].textContent] = {
            'id': titles[i].getAttribute('id')
        };

        if(titles[i+1] && titles[i+1].tagName != 'H2'){
            h2 = titles[i].textContent;
            titlesObj[titles[i].textContent]['titles'] = {};
        }
    }

    if(titles[i].tagName != 'H2'){
        titlesObj[h2]['titles'][titles[i].textContent] = {
            'id': titles[i].getAttribute('id')
        }
    }
}

4) Створюємо структуру нашого вмісту

let navigation = '';

for(let item in titlesObj){
    let subLinks = '';

    if(titlesObj[item]['titles']){
        subLinks = subLinks + '<ul>';

        for(let sub in titlesObj[item]['titles']){
            subLinks = subLinks + `<li><a href="#${titlesObj[item]['titles'][sub]['id']}">${sub}</a></li>`;
        }

        subLinks = subLinks + '</ul>';
    }

    navigation = navigation + `<li><a href="#${titlesObj[item]['id']}">${item}</a>${subLinks}</li>`;
}

5) Додаємо розмітку навігації у необхідну нам область

document.querySelector('#articles_nav ul').innerHTML = navigation;

6) Створюємо та викликаємо функцію яка буде:
– плавно переміщати сторінку в область із заголовком при натисканні на пункт навігації.
– підсвічуватиме потрібний пункт меню при скролі сторінки.

postContentNavigation();

function postContentNavigation(){
    // 6.1) Заносимо всі посилання навігації до змінної
    const smoothLinks = document.querySelectorAll('#articles_nav a');

    if(smoothLinks){

            // 6.2) Навішуємо на кожне посилання подія кліка
            for (let smoothLink of smoothLinks) {
                    smoothLink.addEventListener('click', function (e) {
                            e.preventDefault();
                            const id = smoothLink.getAttribute('href');

                            document.querySelector(id).scrollIntoView({
                                    behavior: 'smooth',
                                    block: 'start'
                            });
                    });
            };

            // 6.3) Підсвічуємо пункти меню 
            $(window).scroll(function(){
                    var $sections = $('.post-content__content h2, .post-content__content h3, .post-content__content h4');
                    $sections.each(function(i,el){
                            var top  = $(el).offset().top-50;
                            var bottom = top +$(el).height();
                            var scroll = $(window).scrollTop();
                            var id = $(el).attr('id');
                            if( scroll > top && scroll < bottom){
                                    $('li.active').removeClass('active');
                                    $('a[href="#'+id+'"]').parents('li').addClass('active');

                            }
                    });
            });
    }
}

Інші статті

Як імпортувати велику базу даних MySQL в OpenServer

Як імпортувати велику базу даних MySQL в OpenServer

Як імпортувати велику базу даних MySQL в OpenServer

Мабуть, усі звикли імпортувати базу даних за допомогою phpMyAdmin. Але ця платформа має обмеження за вагою файлу, який можна завантажити. Тому якщо дамп бази перевищує цю квоту, через phpMyAdmin зробити це не вийде. Сьогодні я покажу альтернативний спосіб завантаження бази даних – через консоль. В OpenServer можна скористатися вбудованою консоллю (але це не обов’язково, можна […]

Діапазон дат у WP_Query – виведення постів за meta_query wordpress

Діапазон дат у WP_Query – виведення постів за meta_query

Діапазон дат у WP_Query – виведення постів за meta_query

Клас WP_Query – це один з інструментів WordPress, який допомагає вивести пости за необхідними параметрами: категорії, сортування, діапазон дат тощо. Список параметрів досить пристойний. Детальніше з ними в документації можна ознайомитися тут: https://developer.wordpress.org/reference/classes/wp_query/ . Деякі параметри досить великі й іноді куди простіше розібратися в них, коли є готові приклади. І у мене якраз такий є. […]