Задать вопрос
iSawyer
@iSawyer

Можно ли оптимизировать код фиксированного оглавления?

Здравствуйте!

Есть в начале статьи статичное оглавление. Нужно сделать, чтобы при скроле статьи к top: 0px закреплялась небольшая position: fixed плашка height: 56px, внутри которой будет название пункта, который сейчас просматривается. При клике на эту небольшую плашку раскрываются все пункты оглавления.

Я это реализовал, но не уверен в чистоте и оптимизации кода. Может кто-то посоветует, как можно сделать лучше. Спасибо.

Получился следующий код:
var
	toc_height = $('nav.toc').height() + $('nav.toc').offset().top, // нижняя точка статичного оглавления
	topic_top[], //массив, в котором расположение (offset().top) каждого заголовка
	topic_text = [], //массив, в котором расположен текст заголовков
	topic_select = $('div.article *[id]'), //выбираю все элементы в теле статьи с ID (в моем случае = все заголовки)
	topic_count = topic_select.length, //считаю количество заголовков
	justExecuted = false; //из интернета для оптимизации количества операция при скролле

for (var i = 0; i < topic_count; i++) {
	topic_top[i] = Math.floor(topic_select.eq(i).offset().top); //сохраняю в массив расположение заголовков
	topic_text = topic_select.eq(i).text(); //сохраняю текст заголовков
}

topic_top[i] = 20000; // конец страницы

$(window).scroll(function() {
	if(justExecuted) {return;} //из интернета для оптимизации количества операция при скролле
	var current_scroll = $(window).scrollTop(); // сохраняю текущую позицию скролла
	if (current_scroll > toc_height) { // если текущий скролл больше нижней точки статичного оглавления
		$('div.fixed-toc').removeClass('hidden'); // делаем фиксированное меню видимым
		if (cur_pos == 0) { // если это первый раз,
			$('ol.toc_menu').clone().appendTo('div.fixed-toc'); // то в фиксированный блок клонируем и вставляем статичный (можно было сразу в HTML коде прописать 2 меню, одно из которых скрыто, но не хотелось дублировать)
			cur_pos = 1; // запомнили, что клонировали, чтобы это больше не повторять
		}
		for (var j = 0; j < topic_count; j++) { // каждый раз при скроле запускаем цикл
			if( (current_scroll < h2[j + 1]) ) { // в котором проверяется положение текущего скрола относительно следующего заголовка. Если заголовок выше, то в фиксированном меню
				$('div.fixed-toc span.title').text(h2_title[j]); // указываем заголовок просматриваемого пункта,
				$('div.fixed-toc li.active').removeClass('active'); // удаляем выделение активного пункта, если оно есть,
				$('div.fixed-toc li').eq(j).addClass('active'); // добавляем выделение к текущему заголовку
			 	break; // выходим из цикла чтобы не перебирать все значения
			}
		}
	} else { // если текущий скролл < положения статичного оглавления, то
		$('div.fixed-toc').addClass('hidden'); // фиксированное меню прячем
	}
	justExecuted = true; //из интернета для оптимизации количества операция при скролле
  	setTimeout(function() {justExecuted = false;}, 100); //из интернета для оптимизации количества операция при скролле
});
  • Вопрос задан
  • 32 просмотра
Подписаться 1 Средний Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы