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

                            }
                    });
            });
    }
}

Другие статьи

Wp Favs — менеджер плагинов для WordPress

Wp Favs — менеджер плагинов для WordPress

Wp Favs — менеджер плагинов для WordPress

Когда ты на регулярной основе создаешь шаблоны для WordPress, то сталкиваешься с одним рутинным моментом, который отнимает у тебя часть времени — загрузка и активация плагинов. Довольно успешно эту проблему решает плагин WP Favs. Вы просто создаете список плагинов, который вы регулярно используете, и потом скопом загружаете его к себе на сайт. Процесс работы с […]

Cloudabove hosting: как очистить кеш на сервере программно.

Cloudabove hosting: как очистить кеш на сервере программно.

Cloudabove hosting: как очистить кеш на сервере программно.

Cloudabove имеет возможность ускорить сайт путем кеширования на сервере. По умолчанию этот кеш очищается каждые 15 минут. Это довольно весомо ускоряет сайт, но при этом влияет на отображение контента. Например, в моем случае опубликованный пользователем отзыв на товар появлялся только спустя 15 минут. Очистить кеш довольно просто. В основе этого лежит GET запрос на https://scout.cloudabove.com/api/cache/purge. […]