/ Сайтостроение / Scripts & jquery / Автоматическое меню, оглавление, измененное состояние меню

Автоматическое меню, оглавление, измененное состояние меню

18.12.2016

847

Меню с изменяемым состоянием может применяться для различных задач, в т.ч. для меню лэндинга или для оглавления длинной страницы. Такое меню состоит из хэш-ссылок для перемещения по самой странице. Смысл в том, чтобы при перемещении по различным блокам соответствующий пункт меню изменялся.

Меню лэндинга

Верста максимально проста и коротка

<ul id="land-menu">
<li class="punkt-action"><a href="#">Главная</a></li>
<li><a href="#features-block">Преимущества</a></li>
<li><a href="#testing">Двигающиеся объекты</a></li>
<li><a href="#forma">Forma</a></li>
<li><a href="#promo">Man is the cruelest animal</a></li>
</ul>

Ссылка на главный блок упрощена — #

CSS

/* Меню лэндинга */

#land-menu {position: fixed; z-index: 100; top: 40%; left: 25px;}

#land-menu li {list-style: none;}

#land-menu li a {
   float: left;
   background-color: rgba(0, 0, 0, 0.8);
   margin-bottom: 5px;
   padding: 5px 15px;
   border-radius: 3px;
   color: #fff;
   width: 100%; /* пункты одинаковой ширины */
   position: relative;
}

#land-menu li a:hover {background-color: #000;}

/* #land-menu .punkt-action a {background-color: #ff5a00 !important;}  выделение цветом фона текста */

/* точка */

#land-menu a:before {
    content: " ";
    border-radius: 50%;
    position: absolute;
    z-index: 1;
    height: 4px;
    width: 4px;
    border: 0;
    background: #000;
    left: -10px;
    top: 50%;
    margin: -2px 0 0 -2px;
    -webkit-transition: all .3s ease-in-out;
    -moz-transition: all .3s ease-in-out;
    -o-transition: all .3s ease-in-out;
    transition: all .3s ease-in-out;
}

#land-menu li a:hover:before {
    height: 12px;
    width: 12px;
    margin: -6px 0 0 -6px;
    border-radius: 100%;	
}	

#land-menu .punkt-action a:before {
    background-color: #ff5a00 !important;
    height: 12px;
    width: 12px;
    margin: -6px 0 0 -6px;
    border-radius: 100%;	
}

Скрипт (не нужно подключать никаких библиотек, как со scrollspy)

$(document).ready(function() {

// Cache selectors
var lastId,
  topMenu = $("#land-menu"),
  topMenuHeight = topMenu.outerHeight() + 15,
  // All list items
  menuItems = topMenu.find("a"),
  // Anchors corresponding to menu items
  scrollItems = menuItems.map(function() {
    var item = $($(this).attr("href"));
    if (item.length) {
      return item;
    }
  });

// Bind click handler to menu items
// so we can get a fancy scroll animation
menuItems.click(function(e) {
  var href = $(this).attr("href"),
    offsetTop = href === "#" ? 0 : $(href).offset().top - topMenuHeight + 1;
  $('html, body').stop().animate({
    scrollTop: offsetTop
  }, 300);
  e.preventDefault();
});

// Bind to scroll
$(window).scroll(function() {
  // Get container scroll position
  var fromTop = $(this).scrollTop() + topMenuHeight;

  // Get id of current scroll item
  var cur = scrollItems.map(function() {
    if ($(this).offset().top < fromTop)
      return this;
  });
  // Get the id of the current element
  cur = cur[cur.length - 1];
  var id = cur && cur.length ? cur[0].id : "";

  if (lastId !== id) {
    lastId = id;
    // Set/remove active class
    menuItems
      .parent().removeClass("punkt-action")
      .end().filter("[href='#" + id + "']").parent().addClass("punkt-action");
  }
});


});

Не корректно работает с плавным скроллингом. т.к. скрипт сам делает этот функционал!

Если мы делаем слайды во всю высоту экрана (min-height: 100vh;), то для нормального скроллинга нужно убрать компенсацию высоты из этой строки:

offsetTop = href === '#' ? 0 : jQuery(href).offset().top - topMenuHeight + 1;

Динамическое формирование меню

Для универсальности данного функционала, необходим алгоритм динамического формирования меню. Либо по заголовкам h2, либо по блокам с id содержащихся в определенном контейнере.

Для того чтобы отследить блоки лэндинга и сформировать из них меню нужно следующее:

1. Обвести все блоки лэндинга общим блоком с id=»landing».
2. Каждому блоку лэндинга задать уникальный id и атрибут title, в котором будет прописан пункт меню
3. Создаем после открывающего тэга body div id=»land-menu-container»
4. Включаем скрипт, обязательно перед предыдущим скриптом

/* Автоматическое создание меню лэндинга */

$(document).ready(function() {

 var ToC = "<ul id='land-menu'>";
 
 var newLine, el, title, link;
 
 $("#landing > div").each(function() {
 el = $(this);
 title = el.attr("title");
 link = "#" + el.attr("id");
 newLine =
 "<li>" +
 "<a href='" + link + "'>" +
 title +
 "</a>" +
 "</li>";
 ToC += newLine;
 });
 
 ToC +=
 "</ul>";
 
 $("#land-menu-container").prepend(ToC);
 
 $("#land-menu > li:first-child").addClass("punkt-action");

});

Рекомендация: заменить атрибут title на name. Потому что title при наведении выводит текст, а name нет.

Автоматическое оглавление

Данный метод jquery (из предыдущего пункта) мы можем применить для автоматического построения оглавления.

Первым делом отыскиваем все h2 в области #post-content и присваиваем им автоматические id

$(document).ready(function() {	 
	 
	var num=1; 
	
	$("#post-content h2").each(function() {
        $(this).attr('id', 'title-' + num);
		num++;
    });	 
	 
});

А после этого, формируем оглавление

$(document).ready(function() {

var ToC =
"<nav role='navigation' class='table-of-contents'>" +
"<ul>";

var newLine, el, title, link;

$("#post-content h2").each(function() {
el = $(this);
title = el.text();
link = "#" + el.attr("id");
newLine =
"<li>" +
"<a href='" + link + "'>" +
title +
"</a>" +
"</li>";
ToC += newLine;
});

ToC +=

"</ul>" +
"</nav>";

$("#all-titles").prepend(ToC);

});

Можно комбинировать с плавным скроллингом

Где-то в верстке необходимо создать div с id=»all-titles». Наилучший вариант вывести его в sitebar напрямую, либо в виде виджета. При этом сайтбар лучше сделать фиксированным, чтоб навигация по содержанию всегда была под рукой.

Проверка: есть ли h2

Можно запрограммировать чтоб блок Оглавление автоматически выводился перед статьей либо в области виджетов. При этом, данный блок можно оформить и задать ему заголовок — Содержание статьи. Но нужна проверка — выводить оглавление только в том случае если есть h2 заголовки. Для этого оборачиваем весь прошлый скрипт (кроме $(document).ready(function()) конструкцией проверки:

if( $('#post-content h2').length ) {
основной скрипт оглавления
}

А в абзац var ToC = добавить после строки nav еще одну строку:

"<p>Оглавление</p>" +

Данное оглавление не отображается в исходном коде, для SEO это не очень хорошо. Подумать как сделать чтоб оглавление выводилось в исходном коде.

Тэги:

Поделится информацией с друзьями

  • Похожие записи
  • Комментарии
  • Вложения
Мобильное меню типа mmenu

Мобильное меню типа mmenu

Адаптируем меню под мобильную версию сайта. При этом необходимо учитывать особенности небольших экранов и конфигурировать под них структуру и стили меню. Функционал mmenu.js Подключаем стили и скрипты: <link rel="stylesheet" href="http://opttour.ru/wp-content/themes/tester/jquery.mmenu.css" Читать далее »

/
Прилепленное меню

Прилепленное меню

Делаем шапку сайта (включающую логотип, меню и контакты) прилепленной к верхнему краю экрана, при перемотке сайта вниз. Оборачиваем необходимый для «прилеплевания» блок в div id=»stick_menu». В данном сайте верстка такая: Читать далее »

Scrollspy jquery

Scrollspy jquery

Скрипт scrollspy jquery отслеживающий положение скрола, в котором мы находится в данный момент. Чаще всего это используется для изменения состояния меню, изменение фона, а также для каких-либо событий. Подключение скрипта Читать далее »

/

Добавить комментарий

Пока нет комментариев. Будь первым!

Автоматическое меню, оглавление, измененное состояние меню
Меняющийся background-image
Рекомендации для васМеняющийся background-imageOpttour.ru
Спасибо! Наш менеджер свяжется с Вами в течении 5 минут.