Автор: Stasyuk Eugene 84 Мітки: 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');

                            }
                    });
            });
    }
}

Інші статті

Як витягнути вміст svg із цього img? Варіант 2 svg

Як витягнути вміст svg із цього img? Варіант 2

Як витягнути вміст svg із цього img? Варіант 2

Якщо ми використовуємо php при розробці, щоб витягнути вміст svg із зображення, буде ще простого. Для цього нам достатньо мати шлях до картинки. У цьому випадку нам на допомогу приходить функція file_get_contents() . Детальніше про нее можна прочитати тут. Приклад використання цієї функції буде виглядати так: Тут потрібно звернути увагу на два моменти: Щоб содержимое […]

Спливаюче вікно на сайті (попап, модальне вікно) pop-up window

Спливаюче вікно на сайті (попап, модальне вікно)

Спливаюче вікно на сайті (попап, модальне вікно)

Коли я тільки освоював ази розробки, спливаюче вікно я робив вручну. Так, так – замість того, щоб знайти якесь готове рішення, я займався цією невдячною справою 🤪. Мені здавалося, що особливо нічого складного в цьому немає. Але, тільки через якийсь час роботи над цим питанням, я почав усвідомлювати, що зробити це не так вже й […]